Computed Fields Scripts API in Siren Investigate
A computed fields script allows you to supplement records with additional data, for example, from a web service or another Elasticsearch index.
context.registerComputations
The context global variable provides a registerComputations function to register computed fields scripts in the Siren Platform.
Simple Example
context.registerComputations({
mainComputation: {
compute: async (records, computeOptions) => {
const firstFieldName = computeOptions.computedFields[0].name; // 'computed-id'
for (const record of records) {
const uuid = await record.getFirstRawFieldValue('generatedUUID');
await context.setComputedField(record, firstFieldName, `${firstFieldName}:${uuid}`);
}
},
outputFields: ['computed-id'],
dependentFields: ['generatedUUID'] // computed field from a previously executed script
}
});
Join with Projection Example
const OUTPUT_FIELDS = ['my_field'];
const getRelatedArticlesByCompanyId = async (companyIds: string[]) => {
const alias = 'company_id';
const scriptSource = `if (doc.containsKey('${alias}') && !doc['${alias}'].empty) { return doc['${alias}'].value; }`
const scriptFields = {
projected_company: {
script: {
source: scriptSource
}
}
};
const joinQuery = {
join: {
indices: ['company'],
on: ['companies', 'id'],
request: {
project: [
{
field: {
name: 'id',
alias
}
}
],
query: {
terms: {
id: companyIds
}
}
}
}
};
const response = await sirenapi.elasticsearch.post('/article/_search', {
size: 10000,
_source: false,
script_fields: scriptFields,
query: joinQuery
});
const groupedByCompanyId = response.hits.hits.reduce((acc, hit) => {
const companyId = hit.fields?.projected_company?.[0];
if (acc[companyId]) {
acc[companyId].push(hit);
} else {
acc[companyId] = [hit];
}
return acc;
}, {});
return groupedByCompanyId;
};
context.registerComputations({
mainComputation: {
compute: async (records, options) => {
const companyIds = await Promise.all(records.map(record => record.getFirstRawFieldValue('id')));
const articlesGroupedByCompanyId = await getRelatedArticlesByCompanyId(companyIds);
for (const record of records) {
for (const { name } of options.computedFields) {
const companyId = await record.getFirstRawFieldValue('id');
const relatedArticles = articlesGroupedByCompanyId[companyId] || [];
const relatedArticleIds = relatedArticles.map(hit => `${hit._index}/_doc/${hit._id}`);
await context.setComputedField(record, name, relatedArticleIds);
}
}
},
outputFields: OUTPUT_FIELDS
}
});
Properties
| Name | Type | Description |
|---|---|---|
[computation-name] |
|
Computed fields script definition. |
ComputationDefinition
An object that defines a computed fields script to register with context.registerComputations.
Properties
| Name | Type | Description |
|---|---|---|
compute |
|
Required. The function definition to be invoked for the computation. |
outputFields |
|
Required. List of computed field names. Must be a non-empty array. Cannot be a function call (e.g., getOutputFields()). |
dependentFields |
|
Optional. List of computed field names this computation depends on. Must be an array if provided. |
ComputationDefinition.compute(records, computeOptions)
The compute function is called with an array of DataRecord objects. Use context.setComputedField(record, fieldName, value) inside the body of compute to set computed field values on a given record. The compute function must be async.
|
|
| Parameter | Type | Description |
|---|---|---|
records |
Array of DataRecord objects to compute fields for. |
|
computeOptions |
Additional compute options which can be read by the compute function definition. |
Returns: Promise<any> | any.
ComputeOptions
Field compute options to determine the relevant operations for the passed records.
| Name | Type | Description |
|---|---|---|
origin |
A |
|
computedFields |
|
An array of computed field objects which are writable in the current compute function’s context. Populating a field with the wrong type will result in an error. |
When to use computed fields scripts?
Use these scripts when you want to supplement a record in the graph with additional data that is only accessible outside of the given record’s definition, for example, via a web service or another Elasticsearch index.
These scripts are executed at a low level, so performance is critical. Inefficient scripts can have a noticeable impact on performance.