Filtering

Filtering allows you search for records within a connection. If you wanted to find all resources who's names start with Projector, you can issue the following request:

Example

query Projectors {
  resources(filters: [
    {field: name, operation: like, value: "Projector%"}
  ]) {
    edges {
      node {
        name
      }
    }
  }
}

Operations

The type FilterOperation defines what operations we are able to use between fields and values. You can think of them as functions that each node is passed through. Each operation has its own semantics, and are explained here for clarity.

Singular

These operations work on a singular field value and take in a singular value. They have type <T>(field: T, value: T) -> bool

The following are the "standard" operations that map nicely to existing operations in logic and programming. The table shows the operation or function to be used with the same value you would pass to "operation", the symbol this most maps to in logic, and its meaning.

op symbol meaning
eq == Do the field and value exactly equal?
ne != Does the field and value differ?
ge >= Is the field greater than or equal to the value?
gt > Is the field great then the value?
le <= Is the field less than or equal to the value?
lt < Is the field less than the value?
isnull == null Is the field null?
notnull != null Is the field specified?

Singular String Operations

These operate on strings and are still singular.

LIKE

like: "~" Match the value against a field. Use % for the wildcard.

eg:

Example

query findMatchingAccounts {
  accounts(filters: {field:name operation:like value:"%Adm%"}) {
    edges {
      node {
        id
        name
      }
    }
  }
}

WORDLIKE

wordlike: "~" Match a word or an ordered expression while excluding punctuations and case sensitivity.

eg:

Example

query findMatchingAccounts {
  accounts(filters: {field:name operation:wordlike value:"Admin"}) {
    edges {
      node {
        id
        name
      }
    }
  }
}

If you have multiple words in the value, they must appear in that order in the field to match.

Hybrid

These operations work on a singular field value and take in a list of values. They have type <T>(field: T, values: List[T]) -> bool

IN

in: IN Matches if the field value equals any in the provided list of values

eg:

"a" in ["a", "p", "l", "e"] => true
5 in [1,2,3,4,5] => true
"target" in ["missing", "value"] => false

NOTIN

notin: NOT IN Excludes if the field value equals any in the provided list of values

eg:

"a" in ["a", "p", "l", "e"] => false
5 in [1,2,3,4,5] => false
"target" in ["missing", "value"] => true

Plural

Plural operations (of which we only have one) work on fields that are themselves lists, and require a list of values to be provided. It has type <T>(field: List[T], values: List[T]) -> bool

This is equivalent to computing if the intersection of field and values is non empty: field_values ∩ values != ∅.

CONTAINS

contains: ANY IN Matches if any value from the field is in the provided values list

Allergy Example

Consider an imaginary dataset containing three items:

[
  {"id": 1, "name": "Sean", "allergies": ["onions", "tomatoes", "grass"]},
  {"id": 2, "name": "Gavin", "allergies": ["peanuts", "gluten"]},
  {"id": 1, "name": "Carl", "allergies": ["peanuts"]},
  {"id": 1, "name": "Tommaso", "allergies": ["cats", "dairy"]},
]

We want to figure out what we can cook with, so we query anyone with either a peanut or onion allergy, using contains:

Example

query knownAllergies {
  people(filters: {field:allergies operation:contains values:["peanuts", "onions"]}) {
    id
    name
    allergies
  }
}

This would return everyone. Let's just focus in on some examples where the values change:

allergies contains ["peanuts", "onions"] => [Sean, Gavin, Carl]
allergies contains ["gluten"] => [Gavin]
allergies contains ["dairy", "grass"] => [Sean, Tommaso]
allergies contains ["peanuts"] => [Gavin, Carl]
allergies contains ["tomatoes", "gluten"] => [Sean, Gavin]
allergies contains ["yeast"] => []

Core GraphQL Custom Field Example

An example of a contains query in Core GraphQL would be filtering Custom Fields by what entities they have.

Example

query filteredCustomFields {
  customFields(filters: {
    field:entities
    operation:contains
    values:["Account", "Contact"]
  }) {
    edges {
      node {
        label      
        entities { name }
      }
    }
  }
}

This will return custom fields that are set up for Accounts or Contacts, regardless of any other entities the custom field is set up for.

Filtering by Custom Field values

Some queries can also filter their results by the value a record holds in a Custom Field, using the separate customFieldFilters argument. This is currently supported on the contacts, contactStats, and catalogue queries.

Each filter names a Custom Field Definition by its ID, an operation, and a value:

Example

query contactsByCustomField {
  contacts(customFieldFilters: [
    {id: "Q3VzdG9tRmllbGREZWZpbml0aW9uOjE1Nw==", operation: eq, value: "Thursday"}
  ]) {
    edges {
      node {
        id
        personalName { name }
      }
    }
  }
}

The id is the Custom Field Definition's ID, which you can find with the customFieldDefinitions query or from the definitionKey returned by an entity's customFieldValues field. The operation accepts the same values as FilterOperation above. Use value for singular operations and values for the list operations — in, notin, and contains.

Multiple filters combine with AND semantics: a record must match every filter in the list.

A few semantics to be aware of:

  • ne and notin also match records where the Custom Field has no value at all. Combine with notnull if you only want records where the field is set to a different value.
  • For checkbox Custom Fields, pass "true", "false", "1" or "0". Other values return an error.
  • isnull finds records where the field is blank; notnull finds records where it has any value.
  • An id that does not resolve to a Custom Field Definition returns an error identifying the filter.