Predicates

Thus far, we have discussed two different types of filters. Each of them allows us to select one or more elements out from a field that allows for many values. Often times, though, we need to apply a filter that allows us to restrict which Record fields are selected. For example, what if we want to select the zip field but only for an address field where the state is not New York? The above examples do not give us any way to do this.

RecordPath provides the user the ability to specify a Predicate. A Predicate is simply a filter that can be applied to a field in order to determine whether or not the field should be included in the results. Like other filters, a Predicate is specified within square brackets. The syntax of the Predicate is <Relative RecordPath> <Operator> <Expression>. The Relative RecordPath works just like any other RecordPath but must start with a . (to reference the current field) or a .. (to reference the current field's parent) instead of a slash and references fields relative to the field that the Predicate applies to. The Operator must be one of:

  • Equals (=)

  • Not Equal (!=)

  • Greater Than (>)

  • Greater Than or Equal To (>=)

  • Less Than (<)

  • Less Than or Equal To (<=)

The Expression can be a literal value such as 50 or Hello or can be another RecordPath.

To illustrate this, let's take the following Record as an example:


{
        "name": "John Doe",
        "workAddress": {
                "number": "123",
                "street": "5th Avenue",
                "city": "New York",
                "state": "NY",
                "zip": "10020"
        },
        "homeAddress": {
                "number": "456",
                "street": "Grand St",
                "city": "Jersey City",
                "state": "NJ",
                "zip": "07304"
        },
        "details": {
                "position": "Dataflow Engineer",
                "preferredState": "NY"
        }
}

Now we can use a Predicate to choose only the fields where the state is not New York. For example, we can use /*[./state != 'NY']. This will select any Record field that has a state field if the state does not have a value of "NY". Note that the details Record will not be returned because it does not have a field named state. So in this example, the RecordPath will select only the homeAddress field. Once we have selected that field, we can continue on with our RecordPath. As we stated above, we can select the zip field: /*[./state != 'NY']/zip. This RecordPath will result in selecting the zip field only from the homeAddress field.

We can also compare the value in one field with the value in another field. For example, we can select the address that is in the person's preferred state by using the RecordPath /*[./state = /details/preferredState]. In this example, this RecordPath will retrieve the workAddress field because its state field matches the value of the preferredState field.

Additionally, we can write a RecordPath that references the "city" field of any record whose state is "NJ" by using the parent operator (..): /*/city[../state = 'NJ'].