Bindings

Overview

Index bindings allow users to store a Lambda function as part of an index definition, and to run that function whenever a new index entry is added or an existing one is updated. It is much more efficient to compute a value once, when an index entry is created or updated, than to compute it every time that the value is needed.

Bindings must be pure Lambda functions: they must not create side effects, such as any additional reads or writes. They are provided with a copy of the document to be indexed and must operate on the document’s values.

+ Functions that cannot be used in bindings include:

Example

To demonstrate, let’s create an index which implements a simple binding function and uses its result as an index term. For the purposes of this demonstration, let’s use the People collection (as created in the indexing tutorials). The goal is to create an index to support a query which looks for people whose age is greater than 100.

The C# version of this example is not currently available.
The Go version of this example is not currently available.
The Java version of this example is not currently available.
client.query(
  q.CreateIndex({
    name: 'people_by_age',
    source: {
      collection: q.Collection('People'),
      fields: {
        over_100: q.Query(q.Lambda('doc', q.GTE(q.Select(['data', 'age'], q.Var('doc')), 100))),
      },
    },
    terms: [{ binding: 'over_100' }],
  })
)
.then((ret) => console.log(ret))
.catch((err) => console.error(
  'Error: [%s] %s: %s',
  err.name,
  err.message,
  err.errors()[0].description,
))
{
  ref: Index("people_by_age"),
  ts: 1644528504640000,
  active: true,
  serialized: true,
  name: 'people_by_age',
  source: {
    collection: Collection("People"),
    fields: {
      over_100: Query(Lambda("doc", GTE(Select(["data", "age"], Var("doc")), 100)))
    }
  },
  terms: [ { binding: 'over_100' } ],
  partitions: 1
}
The Python version of this example is not currently available.
The Shell version of this example is not currently available.
Query metrics:
  •    bytesIn:   283

  •   bytesOut:   444

  • computeOps:     1

  •    readOps:     0

  •   writeOps:     8

  •  readBytes: 2,438

  • writeBytes: 1,335

  •  queryTime:  86ms

  •    retries:     0

The above example uses the GTE function to determine if the age field contains a number greater than or equal to 100, and returns true if it does.

We can now use the new index to support our desired access pattern. The following example uses the people_by_age index to look for people whose age is 100 or more.

The C# version of this example is not currently available.
The Go version of this example is not currently available.
The Java version of this example is not currently available.
client.query(
  q.Map(
    q.Paginate(q.Match(q.Index('people_by_age'), true)),
    q.Lambda('person', q.Get(q.Var('person')))
  )
)
.then((ret) => console.log(ret))
.catch((err) => console.error(
  'Error: [%s] %s: %s',
  err.name,
  err.message,
  err.errors()[0].description,
))
{
  data: [
    {
      ref: Ref(Collection("People"), "323244160540739072"),
      ts: 1644528503860000,
      data: {
        first: 'Alan',
        last: 'Turing',
        age: 107,
        degrees: [ 'BA', 'MA', 'MS', 'PhD' ],
        letter: 'B'
      }
    },
    {
      ref: Ref(Collection("People"), "323244160541786624"),
      ts: 1644528503860000,
      data: {
        first: 'Grace',
        last: 'Hopper',
        age: 119,
        degrees: [ 'BA', 'MA', 'PhD' ],
        letter: 'C'
      }
    }
  ]
}
The Python version of this example is not currently available.
The Shell version of this example is not currently available.
Query metrics:
  •    bytesIn:  134

  •   bytesOut:  507

  • computeOps:    1

  •    readOps:    3

  •   writeOps:    0

  •  readBytes:  333

  • writeBytes:    0

  •  queryTime: 21ms

  •    retries:    0

Was this article helpful? 

We're sorry to hear that.
Tell us how we can improve!
Visit Fauna's forums or email docs@fauna.com

Thank you for your feedback!