# Fuuz Bindings: $predicateFilter

> Executive Summary Every model in the Fuuz GraphQL API has a generic WhereInput type used to filter queries against that model. These WhereInput types…

Source: https://www.fuuz.com/help/article
Last updated: 2026-06-07

How-To Guides · Expressions and scripting


Last updated June 7, 2026, 4:53 PM UTC

## Executive Summary

Every model in the Fuuz GraphQL API has a generic *WhereInput* type used to filter queries against that model. These *WhereInput* types assign a *PredicateInput* type to each field on the model. If you have made a query against a Fuuz GraphQL API you have likely used a *WhereInput* to filter the results. These predicates provide a quick and easy way to define filters through a Fuuz GraphQL API, making them a natural fit for the internal workings of screens and Data Flows.

### Example:

| **Query**`1. # query for CalendarEvents... 2. query GetEvents ($where:CalendarEventWhereInput){ 3. calendarEvent(where: $where) { 4. id 5. timeZone 6. calendarId 7. } 8. }` | **Variables**`1. // ...where the CalendarEvent’s timeZone is 'America/Detroit': 2. { 3. "where": { 4. "timeZone": { 5. "_eq": "America/Detroit" 6. } 7. } 8. }` | ---  `1. // ...with Calendar ID "myCalendar" and priority greater than 100: 2. { 3. "where": { 4. "calendarId": { 5. "_eq": "myCalendar" 6. }, 7. "priority": { 8. "_gt": 100 9. } 10. } 11. }` |
| --- | --- | --- |

---

## Predicates

A *predicate* can be thought of as a “test” that data must pass in order to be accepted by the filter: if you’re using this binding, then you should be familiar with this concept from Jsonata’s `$filter` function. The main difference between `$filter` and `$predicateFilter` is one of representation:

**$filter**

- A predicate is represented as a function.
- An element is accepted if the predicate function returns `true` when applied to it.
- Even relatively simple predicates need to be expressed in terms of functions:

	1. **Example:**

	`$filter( $data, function($element) { $element.code = "A" and $element.active = true } )`

**$predicateFilter**

- A predicate is expressed as an object of *predicate inputs*. (Described later.)
- An element is accepted if it satisfies all of the inputs.
- Predicates look more like the data they are being used to filter:

	-
	1. **Example:**

	`$predicateFilter( $data, { "code": { "_eq": "A" }, "active": { "_eq": true } } )`

## InfoThere are subtle differences between these two example snippets! For example, $predicateFilter uses case-insensitive comparison for strings by default.Predicate Inputs

### Universal Predicate Inputs

These predicate inputs are available for use against fields of any type.

#### Equality Comparison (`_eq`)

An equality comparison. Matches when the field value equals the provided input value.

![Info](https://www.fuuz.com/assets/help/c4804ad0cad4.webp)String equality is case-insensitive by default (see caseSensitiveComparison)**Payload**

`1. [
2. { "id": 1, "label": "One" },
3. { "id": 2, "label": "Two" },
4. { "id": 3, "label": "Three" },
5. { "id": 4, "label": "Four" }
6. ]`**Transform**

`1. $predicateFilter(
2. $,
3. { "id": { "_eq": 1 } }
4. )`**Result**

`1. [
2. { "id": 1, "label": "One" }
3. ]`#### Is-Null (`_isNull`)

A null-checking comparison.

- An input value of `true` matches where the field value is `null` or undefined.
- Any other input value matches where the field value is not null.

**Payload**

`1. [
2. { "id": 1, "userId": "example" },
3. { "id": 2, "userId": null },
4. { "id": 3, "userId": "test" },
5. { "id": 4 }
6. ]`**Transform**

`1. $predicateFilter(
2. $,
3. { "userId": { "_isNull": true } }
4. )`**Result**

`1. [
2. { "id": 2, "userId": null },
3. { "id": 4 }
4. ]`#### List Membership (`_in`)

Matches when the field value is contained in the list provided by the input value. *(Membership is tested using the same rules as* `_eq`*.)*

**Payload**

`1. [
2. {
3. "id": "myCalendarEvent1",
4. "calendarId": "myCalendar",
5. "eventJson": { /* ... */ }
6. },
7. {
8. "id": "otherCalendarEvent1",
9. "calendarId": "otherCalendar",
10. "eventJson": { /* ... */ }
11. },
12. {
13. "id": "testCalendarEvent",
14. "calendarId": "testCalendar",
15. "eventJson": { /* ... */ }
16. },
17. {
18. "id": "myCalendarEvent2",
19. "calendarId": "myCalendar",
20. "eventJson": { /* ... */ }
21. },
22. {
23. "id": "otherCalendarEvent2",
24. "calendarId": "otherCalendar",
25. "eventJson": { /* ... */ }
26. }
27. ]`**Transform**

`1. $predicateFilter(
2. $,
3. { "calendarId": { "_in": ["myCalendar", "testCalendar"] } }
4. )`**Result**

`1. [
2. {
3. "id": "myCalendarEvent1",
4. "calendarId": "myCalendar",
5. "eventJson": {...}
6. },
7. {
8. "id": "testCalendarEvent",
9. "calendarId": "testCalendar",
10. "eventJson": {...}
11. },
12. {
13. "id": "myCalendarEvent2",
14. "calendarId": "myCalendar",
15. "eventJson": {...}
16. }
17. ]`#### Comparators (`_gt`/`_lt`/`_gte`/`_lte`)

These predicate inputs compare the field value to the input value using their respective comparisons.

| `_gt` | = | (strictly) greater than |
| --- | --- | --- |
| `_lt` | = | (strictly) less than |
| `_gte` | = | greater than or equal |
| `_lte` | = | less than or equal |

![Info](https://www.fuuz.com/assets/help/c4804ad0cad4.webp)String equality is case-insensitive by default (see caseSensitiveComparison)
**Payload**

`1. [
2. { "id": 1, "label": "One" },
3. { "id": 2, "label": "Two" },
4. { "id": 3, "label": "Three" },
5. { "id": 4, "label": "Four" }
6. ]`**Tran** **sform
1. $predicateFilter(
2. $,
3. { "id": { "_gt": 2 } }
4. )** **Result**

`1. [
2. { "id": 3, "label": "Three" },
3. { "id": 4, "label": "Four" }
4. ]`### String-Only Predicate Inputs

These predicate inputs can be used against string fields.

#### Match Start/End of String (`_startsWith`/`_endsWith`)

Performs a starts/ends-with comparison against the field value. Matches if the field value starts/ends with the input value.

**Payload**

`1. [
2. {
3. "id": "myCalendarEvent1",
4. "calendarId": "myCalendar",
5. "eventJson": { /* ... */ }
6. },
7. {
8. "id": "otherCalendarEvent1",
9. "calendarId": "otherCalendar",
10. "eventJson": { /* ... */ }
11. },
12. {
13. "id": "testCalendarEvent",
14. "calendarId": "testCalendar",
15. "eventJson": { /* ... */ }
16. },
17. {
18. "id": "myCalendarEvent2",
19. "calendarId": "myCalendar",
20. "eventJson": { /* ... */ }
21. },
22. {
23. "id": "otherCalendarEvent2",
24. "calendarId": "otherCalendar",
25. "eventJson": { /* ... */ }
26. }
27. ]`**Transform**

`1. $predicateFilter(
2. $,
3. { "id": { "_endsWith": "Event1" } }
4. )`**Result**

`1. [
2. {
3. "id": "myCalendarEvent1",
4. "calendarId": "myCalendar",
5. "eventJson": { /* ... */ }
6. },
7. {
8. "id": "otherCalendarEvent1",
9. "calendarId": "otherCalendar",
10. "eventJson": { /* ... */ }
11. }
12. ]`#### Contains Substring (`_contains`)

Performs a contains comparison against the field value. Matches if the field value contains the input value. The input value can be either a string or a regular expression.

**Payload**

`1. [
2. { "id": "hourly", "label": "Hourly" },
3. { "id": "daily", "label": "Daily" },
4. { "id": "weekly", "label": "Weekly" },
5. { "id": "monthly", "label": "Monthly" },
6. { "id": "yearly", "label": "Yearly" }
7. ]`![Info](https://www.fuuz.com/assets/help/c4804ad0cad4.webp)`Regular expressions have their own case-sensitivity options, so make sure to use the /i flag if you want case-insensitive regular expressions:`**Transform**

`1. $predicateFilter(
2. $,
3. { "label": { "_contains": "rly" } }
4. )`**Result**

`1. [
2. { "id": "hourly", "label": "Hourly" },
3. { "id": "yearly", "label": "Yearly" }
4. ]`**Payload**

`1. [
2. { "id": "hourly", "label": "Hourly" },
3. { "id": "daily", "label": "Daily" },
4. { "id": "weekly", "label": "Weekly" },
5. { "id": "monthly", "label": "Monthly" },
6. { "id": "yearly", "label": "Yearly" }
7. ]`**Transform**

`1. $predicateFilter(
2. $,
3. { "label": { "_contains": /[aeiou]{2}/i } }
4. )`**Result**

`1. [
2. { "id": "hourly", "label": "Hourly" },
3. { "id": "daily", "label": "Daily" },
4. { "id": "weekly", "label": "Weekly" },
5. { "id": "yearly", "label": "Yearly" }
6. ]`### JSON Predicate Inputs

These predicate inputs can be used on JSON object fields. Unlike the previous examples, JSON predicate input values are provided as objects with two properties:

`1. {
2. // the object path to test the value against.
3. // if empty, the value is tested against the whole object.
4. "path": string[],
5. // the value to test against the path on the object.
6. "value": any
7. }`#### Contains Object Comparison (`_containsObject`)

Performs an object contains comparison. The predicate matches when the JSON field contains the provided JSON path/value entries.

**Payload** 1. **[{ "data": { "id": 1, "code": "A", "active": true } },**
2. **{ "data": { "id": 2, "code": "B", "active": true } },**
3. **{ "data": { "id": 3, "code": "A", "active": false } },**
4. **{ "data": { "id": 4, "code": "B", "active": false } },**
5. **{ "data": { "id": 5, "code": "A", "active": true} }]**

**Transform**

`1. $predicateFilter(
2. $,
3. {
4. "data": {
5. "_containsObject": {
6. "path": [],
7. "value": { "code": "A", "active": true }
8. }
9. }
10. }
11. )`**Result**

`1. [
2. { "data": { "id": 1, "code": "A", "active": true } },
3. { "data": { "id": 5, "code": "A", "active": true } }
4. ]`#### InfoThis function _always_ treats strings case-sensitively. Case-insensitive behavior can be achieved using other predicate inputs.Object Has Key (`_has`)

Performs an object-has-key comparison. The predicate matches when the JSON field value contains a key matching the input value.

**Payload**

`1. [
2. { "id": 1, "metadata": { "user": { "id": "example" } } },
3. { "id": 2, "metadata": { "user": { "id": null } } },
4. { "id": 3, "metadata": { "user": { "id": "test" } } },
5. { "id": 4 }
6. ]`**Transform**

`1. $predicateFilter(
2. $,
3. {
4. "metadata": {
5. "_has": {
6. "path": ["user"],
7. "value": "id"
8. }
9. }
10. }
11. )`**Result**

`1. [
2. { "id": 1, "metadata": { "user": { "id": "example" } } },
3. { "id": 2, "metadata": { "user": { "id": null } } },
4. { "id": 3, "metadata": { "user": { "id": "test" } } }
5. ]`#### Using Universal Predicate Inputs on JSON Objects

All prior predicate inputs (`_eq`/`_isNull`/`_in`/etc.) can be used on JSON objects as well. These input values can be provided in two ways:

| Nested StylePredicate inputs can be nested under any number of property names, implicitly defining the path and value to test the predicate against:`/* Nested Style (implicit `path`/`value`) */ $predicateFilter(   [     { "id": 1, "metadata": { "user": { "id": "example" } } },     { "id": 2, "metadata": { "user": { "id": null } } },     { "id": 3, "metadata": { "user": { "id": "test" } } },     { "id": 4 }   ],   {     "metadata": {       "user": {         "id": { "_in": ["example", "test"] }       }     }   } ) /* -> [   { "id": 1, "metadata": { "user": { "id": "example" } } },   { "id": 3, "metadata": { "user": { "id": "test" } } } ] */`This approach is intuitive, but can lead to some issues when property names conflict with predicates (see `Special Cases`). It also doesn't translate as neatly to query filters, since this structure doesn't match the `JSONPredicateInput` type used for `JSONObject` query fields.`// This nested-style predicate... {   "metadata": {     "user": {       "id": {         "_in": ["example", "test"],         "_lt": "foobar"       }     }   } }` | JSON Predicate Input StyleThe `path`/`value` object can be provided to any predicate input to run that predicate against the given path on that field value.`/* JSON Predicate Input Style (explicit `path`/`value`) */ $predicateFilter(   [     { "id": 1, "metadata": { "user": { "id": "example" } } },     { "id": 2, "metadata": { "user": { "id": null } } },     { "id": 3, "metadata": { "user": { "id": "test" } } },     { "id": 4 }   ],   {      "metadata": {       "_in": {         "path": ["user", "id"],         "value": ["example", "test"]       }     }   } ) /* -> [   { "id": 1, "metadata": { "user": { "id": "example" } } },   { "id": 3, "metadata": { "user": { "id": "test" } } } ] */`This approach is more explicit and better-reflects the `JSONPredicateInput` type used for filtering `JSONObject` fields. However, it is more awkward to compose complex object filters in this way, requiring the use of an `_and` predicate to apply multiple filters to the same object.// ...Composed in the `JSONPredicateInput` style {   "_and": [     {       "metadata": {         "_in": {           "path": ["user", "id"],           "value": ["example", "test"]         }       }     },     {       "metadata": {         "_lt": {           "path": ["user", "id"],           "value": "foobar"         }       }     }   ] } |
| --- | --- |

### Composite Predicate Inputs

#### `_and`/`_or`/`_not`

Predicates can be logically combined under `_and`/`_or`/`_not` as-follows:

`1. {
2. // passes if all predicates in the array pass.
3. "_and": [ {/* <predicate 1> */}, {/* <predicate 2> */}, ...],
4. // passes if any predicates in the array pass.
5. "_or": [ {/* <predicate 1> */}, {/* <predicate 2> */}, ...],
6. // passes if the given predicate does not pass.
7. "_not": {/* <predicate> */}
8. }`## Using the `$predicateFilter` Binding

### Payloads

Predicate filters can be applied to two kinds of payloads: arrays and objects.

#### Array Payloads

Array payloads are filtered in a similar way as with the `$filter` function. Each element of the array is tested individually and included in the result only if it satisfies the provided predicate.

**Payload**

`[ { "id": 1, "code": "A" }, { "id": 2, "code": "B" }, { "id": 3, "code": "a" } ]`**Transform**

`$predicateFilter( $, { "code": { "_eq": "A" } } )`**Result**

`[ { "id": 1, "code": "A" }, { "id": 3, "code": "a" } ]`#### Object Payloads

Object payloads are filtered in a similar way as with the `$sift` function. Each property of the object is included in the result only if its value satisfies the provided predicate.

**Payload**

`{ "foo": { "id": 1, "code": "A" }, "bar": { "id": 2, "code": "B" }, "baz": { "id": 3, "code": "a" } }`**Transform**

`$predicateFilter( $, { "code": { "_eq": "A" } } )`**Result**

`{ "foo": { "id": 1, "code": "A" }, "baz": { "id": 3, "code": "a" } }`### Special Cases

#### Dates

Dates in JSON data are typically represented as formatted strings. This is also true for query filters against `DateTime` fields, since the GraphQL API knows which fields are supposed to be dates and which fields are just plain strings.

This is *not* true for the `$predicateFilter` binding; it *does not* know when a given string is supposed to be a date or not, and therefore ***will not compare formatted strings correctly as dates.***

For example:

`/* THIS WILL NOT FILTER DATES PROPERLY */ $predicateFilter(   [     { "id": 0, "code": "CODE-A", "time": "2024-01-01T00:00:00.000-04:00" },     { "id": 1, "code": "CODE-B", "time": "2024-01-01T00:00:00.000-02:00" },     { "id": 2, "code": "CODE-C", "time": "2024-01-01T00:00:00.000+00:00" },     { "id": 3, "code": "CODE-D", "time": "2024-01-01T00:00:00.000+02:00" },     { "id": 4, "code": "CODE-E", "time": "2024-01-01T00:00:00.000+04:00" }   ],   { "time": { "_gte": "2024-01-01T00:00:00.000Z" } } ) /* -> [] (INCORRECT) */`When working with dates, ensure that both your payload *and* predicate fields are cast to `Date` objects or `moment` instances if you want to compare them.

`$predicateFilter(   [     { "id": 0, "code": "CODE-A", "time": $moment("2024-01-01T00:00:00.000-04:00") },     { "id": 1, "code": "CODE-B", "time": $moment("2024-01-01T00:00:00.000-02:00") },     { "id": 2, "code": "CODE-C", "time": $moment("2024-01-01T00:00:00.000+00:00") },     { "id": 3, "code": "CODE-D", "time": $moment("2024-01-01T00:00:00.000+02:00") },     { "id": 4, "code": "CODE-E", "time": $moment("2024-01-01T00:00:00.000+04:00") }   ],   { "time": { "_gte": $moment("2024-01-01T00:00:00.000Z") } } ) /* -> [   { "id": 0, "code": "CODE-A", "time": "2024-01-01T04:00:00.000Z" },   { "id": 1, "code": "CODE-B", "time": "2024-01-01T02:00:00.000Z" },   { "id": 2, "code": "CODE-C", "time": "2024-01-01T00:00:00.000Z" } ] */`#### Keys Conflicting with Predicate Inputs

Sometimes, payload elements will contain properties with names matching predicate input names (like `_eq` or `_in`).

For an (admittedly-contrived) example, you might want to remove filters from a `WhereInput` object when they contain `"_isNull": true`:

`/* THIS WILL NOT FILTER PROPERLY */ $predicateFilter(   /* A hypothetical WhereInput to be used in a query */   {     "name": { "_contains": "foo" },     "metadata": { "_isNull": false },     "userId": { "_in": ["example", "test"], "_isNull": true }   },   /* trying to filter out fields containing `{ "_isNull": true }` */   { "_not": { "_isNull": { "_eq": true } } } )`The property name "`_isNull`" conflicts with the `_isNull` predicate input, making the filter ambiguous. In these ambiguous cases, the `$predicateFilter` binding *always* prefers to interpret it as a predicate instead of an implicit path. To disambiguate, use the explicit `path`/`value` style described in the JSON Predicate Input Style section.

`$predicateFilter(   {     "name": { "_contains": "foo" },     "metadata": { "_isNull": false },     "userId": { "_in": ["example", "test"], "_isNull": true }   },   {     "_not": {       /* the `path`/`value` style for JSON properties is unambiguous */       "_eq": {         "path": ["_isNull"],         "value": true       }     }   } ) /* -> {   "name": { "_contains": "foo" },   "metadata": { "_isNull": false } } */`### Options

#### `caseSensitiveComparison`

*(Boolean: defaults to* `false`)

While `false` (the default) string values will be compared case-insensitively. (Both predicate and payload field values will be converted to lowercase for comparison.) This reflects the behavior of a Fuuz GraphQL API, which matches string fields case-insensitively.

While `true`, string fields will be kept in their original casing for all comparisons.

`$predicateFilter(   [     { "id": 1, "code": "A" },     { "id": 2, "code": "B" },     { "id": 3, "code": "a" }   ],   { "code": { "_gte": "B" } } ) /* -> [{ "id": 2, "code": "B" }] */ $predicateFilter(   [     { "id": 1, "code": "A" },     { "id": 2, "code": "B" },     { "id": 3, "code": "a" }   ],   { "code": { "_gte": "B" } },   { "caseSensitiveComparison": true } ) /* -> [   { "id": 2, "code": "B" },   { "id": 3, "code": "a" } ] */`## $predicateFilter Examples

Equality ComparisonAn equality comparison. Matches when the field value equals the provided input value.

`$predicateFilter(   [     { "id": 1, "label": "One" },     { "id": 2, "label": "Two" },     { "id": 3, "label": "Three" },     { "id": 4, "label": "Four" }   ],   {     "id": { "_eq": 1 }   } )`Result:

`[{ "id": 1, "label": "One" }]`
Object Contains ComparisonPerforms an object contains comparison. The predicate matches when the JSON field contains the provided JSON path/value entries.

`$predicateFilter(   [     { "data": { "id": 1, "code": "A", "active": true } },     { "data": { "id": 2, "code": "B", "active": true } },     { "data": { "id": 3, "code": "A", "active": false } },     { "data": { "id": 4, "code": "B", "active": false } },     { "data": { "id": 5, "code": "A", "active": true } }   ],   {     "data": {       "_containsObject": {         "path": [],         "value": { "code": "A", "active": true }       }     }   } )`Result:

`[   { "data": { "id": 1, "code": "A", "active": true } },   { "data": { "id": 5, "code": "A", "active": true } } ]`
Object Payload Property FilteringObject payloads are filtered in a similar way as with the `$sift` function. Each property of the object is included in the result only if its value satisfies the provided predicate.

`$predicateFilter(   {     "foo": { "id": 1, "code": "A" },     "bar": { "id": 2, "code": "B" },     "baz": { "id": 3, "code": "a" }   },   { "code": { "_eq": "A" } } )`Result:

`{ "foo": { "id": 1, "code": "A" },   "baz": { "id": 3, "code": "a" } }`

### Need more help?

Ask the Fuuz community, or open a ticket with Fuuz support.

[Ask the community](https://www.fuuz.com/community) [Open a ticket](https://support.fuuz.com/portal/en/newticket)

On this page

[Executive Summary](#executive-summary)

[Predicates](#predicates)

There are subtle differences between these two example snippets! For example, $predicateFilter uses case-insensitive comparison for strings by default.Predicate Inputs

[Open](#there-are-subtle-differences-between-these-two-example-snipp)

[Using the $predicateFilter Binding](#using-the-predicatefilter-binding)

[$predicateFilter Examples](#predicatefilter-examples)
