Expressions

Introduction

Expressions allow developers to execute conditional logic when running scripts or policies. These operators are available to construct logic for use in the aggregation pipeline stages. The Expression module exposes logical operators that allow programmers to make decisions based on certain conditions.

Expressions are meant to replace Cortex scripts as much as is possible. They're a portable expression of logic that can read and act on data as a .json document, similar to the MongoDB query language, but now moved over to the server side. But Expressions can do more than just read data.

Expressions, or Operator Expressions, are similar to functions that take arguments. In general, these expressions take an array of arguments and have the following form:const{ evaluate } = require ('expressions')

So a simple Expression would look like this: { $add: [1, 2] } → 3

Expressions can include field paths, literals, operators, accumulators, and variables. Expressions can also be nested.

In general, these expressions take an array of arguments that have the following form:

  • Fields '$field'

  • Literals 1, "foo", etc.

  • Operators { $op }

  • Accumulators { $op } in group stage

  • Variables '$$ROOT'

Expressions vs. Triggers

How Are Expressions Different From Triggers? Because triggers happen at run-time (on the client-side through a web browser), and an Expression happens on Medable's side within the server, Expressions are at least 10x more efficient than triggers.

Expression Pipelines

A pipeline is a series of Expressions that operate on an array of values or on a cursor. This can be useful, for example, by adding Expression pipelines to cursors. For example, when performing a "find" operation in a script and Expression Pipeline can be added to the end of the script to transform the output.

Example: Running a Pipeline:

runPipeline ([{ $set: {foo: 'bar'}]...find())

  • Pipelines chain streams together.

  • The Cursor is a pointer in memory that knows which Expression is currently running.

  • Expressions operate on each document within a Cursor and then output the results.

  • Pipelines operate on arrays

  • Expressions operate on an object

  • Users can also pass arrays to Pipelines

The following example adds a pipeline stage that sets the value of foo to bar in output document and streams it through:

Note: Expressions operate in Cortex like transforms.

Transform: cursor.transform('md_foo')

Expression: cursor.expressionPipeline('md_pipe')

Validators

Validators take an Expression and returns a boolean.

The Validator is $cond in the below example

{ $cond: {
if: '$value',
then: true,
else: false }}

Guidelines

  1. Expressions must be in an array because they expect stages.

  2. The source of the Expression must be an array too.

  3. The input for Expressions is a document or several documents.

  4. An Expression is simply a .json document starting with $

How To Use An Expression

  1. Require the expressions module in a script

    const { run } = require('expressions')

return run({
$concat: ['', '$$ROOT.foo', '.bar']
}, {foo: 'bar'})

Details:

When passing in a Document to the Expression, Expressions get a number of variables. In the above example .foo is the root document (may be used either as $$Root.docName or .docName) The root document is currently accessed document

Example: Using a Pipeline and Passing in a Cursor:

const { run, pipeline: { run: runPipeline } } = require ('expressions')

return runPipeline([{
  $project: ‘$email’
}],

org.objects.accounts.find()

)

Example: Using the Root Document to Concatenate Values:

Details:

The Expressions takes an array and for each [{ foo: ‘bar’}] it projects a single document by concatenating the values, using the root document as the particular context.

const { run, pipeline: { run: runPipeline } } = require ('expressions')

return runPipeline([{
  $project: {
    x: { $concat: ['', '$$ROOT.foo', '.bar'] }
  }
}],

[{ foo: ‘bar’}, { foo: ‘b’ }]

)

What Can We Do With Expressions?

Create transformations to hide output data (PHI, for example)

Create transformation stage out of a cursor that would get rid of some values

Note: Expressions are about 10x more efficient than scripts because they operate server-side rather than client-side. Everything happens on the Cortex end of things. Getting away from using transforms and moving towards using Expressions for tools like a Screening Tool

Last updated