Filter query results / search queries

The where argument

You can use the where argument in your queries to filter results based on some field’s values (even nested objects’ fields). You can even use multiple filters in the same where clause using the _and or the _or operators.

For example, to fetch data for an author whose name is “Sidney”:

 query {
   authors(
     where: {name: {_eq: "Sidney"}}
   ) {
     id
     name
   }
 }

You can also use nested objects` fields to filter rows from a table and also filter the nested objects as well.

For example, to fetch a list of authors who have articles with a rating greater than 4 along with those articles:

 query {
   authors (where: {articles: {rating: {_gt: 4}}}) {
     id
     name
     articles (where: {rating: {_gt: 4}}) {
       id
       title
       rating
     }
   }
 }

Here _eq and _gt are examples of comparison operators that can be used in the where argument to filter on equality.

You can see the complete specification of the where argument in the API reference.

Comparision operators

Let’s take a look at different comparision operators that can be used to filter results.

Equality operators (_eq, _neq)

The _eq (equal to) or the _neq (not equal to) operators are compatible with any Postgres type other than json or jsonB (like Integer, Float, Double, Text, Boolean, Date/Time/Timestamp, etc.).

For more details on equality operators and Postgres equivalents, refer to the API reference.

The following are examples of using the equality operators on different types.

Example: Integer (works with Double, Float, Numeric, etc.)

Fetch data about an author whose id (an integer field) is equal to 3:

Variables

Example: String or Text

Fetch a list of authors with name (a text field) as “Sidney”:

Variables

Example: Boolean

Fetch a list of articles that have not been published (is_published is a boolean field):

Variables

Example: Date (works with Time, Timezone, etc.)

Fetch a list of articles that were published on a certain date (published_on is a Date field):

Variables

Greater than or less than operators (_gt, _lt, _gte, _lte)

The _gt (greater than), _lt (less than), _gte (greater than or equal to), _lte (less than or equal to) operators are compatible with any Postgres type other than json or jsonB (like Integer, Float, Double, Text, Boolean, Date/Time/Timestamp, etc.).

For more details on greater than or less than operators and Postgres equivalents, refer to the API reference.

The following are examples of using these operators on different types:

Example: Integer (works with Double, Float, etc.)

Fetch a list of articles rated 4 or more (rating is an integer field):

Variables

Example: String or Text

Fetch a list of authors whose names begin with M or any letter that follows M (essentially, a filter based on a dictionary sort):

Variables

Example: Date (works with Time, Timezone, etc.)

Fetch a list of articles that were published on or after date “01/01/2018”:

Variables

List based search operators (_in, _nin)

The _in (in a list) and _nin (not in list) operators are used to compare field values to a list of values. They are compatible with any Postgres type other than json or jsonB (like Integer, Float, Double, Text, Boolean, Date/Time/Timestamp, etc.).

For more details on list based search operators and Postgres equivalents, refer to the API reference.

The following are examples of using these operators on different types:

Example: Integer (works with Double, Float, etc.)

Fetch a list of articles rated 1, 3 or 5:

Variables

Example: String or Text

Fetch a list of those authors whose names are NOT part of a list:

Variables

Text search or pattern matching operators (_like, _similar, etc.)

The _like, _nlike, _ilike, _nilike, _similar, _nsimilar, _regex, _nregex, _iregex, _niregex operators are used for pattern matching on string/text fields.

For more details on text search operators and Postgres equivalents, refer to the API reference.

Example: _like

Fetch a list of articles whose titles contain the word “amet”:

Variables

Note

_like is case-sensitive. Use _ilike for case-insensitive search.

Example: _similar

Fetch a list of authors whose names begin with A or C:

Variables

Note

_similar is case-sensitive

JSONB operators (_contains, _has_key, etc.)

The _contains, _contained_in, _has_key, _has_keys_any and _has_keys_all operators are used to filter based on JSONB columns.

For more details on JSONB operators and Postgres equivalents, refer to the API reference.

Example: _contains

Fetch all authors living within a particular pincode (present in address JSONB column):

Variables

Example: _has_key

Fetch authors if the phone key is present in their JSONB address column:

Variables

PostGIS spatial relationship operators (_st_contains, _st_crosses, etc.)

The _st_contains, _st_crosses, _st_equals, _st_intersects, _st_overlaps, _st_touches, _st_within and _st_d_within operators are used to filter based on geometry like columns.

_st_d_within and _st_intersects can be used on geography columns also.

For more details on spatial relationship operators and Postgres equivalents, refer to the API reference.

Use JSON representation (see GeoJSON) of geometry and geography values in variables as shown in the following examples:

Example: _st_within

Fetch a list of geometry values which are within the given polygon value:

Variables

Example: _st_d_within

Fetch a list of geometry values which are 3 units from given point value:

Variables

Filter or check for null values (_is_null)

Checking for null values can be achieved using the _is_null operator.

For more details on the _is_null operator and Postgres equivalent, refer to the API reference.

Example: Filter null values in a field

Fetch a list of articles that have a value in the published_on field:

Variables

Intersect operators on RASTER columns (_st_intersects_rast, etc)

Intersect operators on columns with raster type are supported. Please submit a feature request via GitHub if you want support for more functions.

For more details on intersect operators on raster columns and Postgres equivalents, refer to the API reference.

Example: _st_intersects_rast

Filter the raster values which intersect the input raster value.

Executes the following SQL function:

boolean ST_Intersects( raster <raster-col> , raster <raster-value> );
Variables

Example: _st_intersects_geom_nband

Filter the raster values which intersect the input geometry value and optional band number.

Executes the following SQL function:

boolean ST_Intersects( raster <raster-col> , geometry geommin , integer nband=NULL );
Variables

Example: _st_intersects_nband_geom

Filter the raster values (with specified band number) which intersect the input geometry value.

Executes the following SQL function:

boolean ST_Intersects( raster <raster-col> , integer nband , geometry geommin );
Variables

Filter based on failure of some criteria (_not)

The _not operator can be used to fetch results for which some condition does not hold true. i.e. to invert the filter set for a condition.

Example: _not

Fetch all authors who don’t have any published articles:

Variables

Using multiple filters in the same query (_and, _or)

You can group multiple parameters in the same where argument using the _and or the _or operators to filter results based on more than one criteria.

Note

You can use the _or and _and operators along with the _not operator to create arbitrarily complex boolean expressions involving multiple filtering criteria.

Example: _and

Fetch a list of articles published in a specific time-frame (for example: in year 2017):

Variables

Note

Certain _and expressions can be expressed in a simpler format using some syntactic sugar. See the API reference for more details.

Example: _or

Fetch a list of articles rated more than 4 or published after “01/01/2018”:

Variables

Note

The _or operator expects an array of expressions as input. If an object is passed as input it will behave like the _and operator as explained in the API reference

Filter nested objects

The where argument can be used in array relationships as well to filter the nested objects. Object relationships have only one nested object and hence they do not expose the where argument.

Example:

Fetch all authors with only their 5 rated articles:

Variables

Filter based on nested objects’ fields

You can use the fields of nested objects as well to filter your query results.

For example:

   query {
     articles (where: {author: {name: {_eq: "Sidney"}}}) {
       id
       title
     }
   }

The behaviour of the comparision operators depends on whether the nested objects are a single object related via an object relationship or an array of objects related via an array relationship.

  • In case of an object relationship, a row will be returned if the single nested object satisfies the defined condition.
  • In case of an array relationship, a row will be returned if any of the nested objects satisfy the defined condition.

Let’s look at a few use cases based on the above:

Fetch if the single nested object defined via an object relationship satisfies a condition

Example:

Fetch all articles whose author’s name starts with “A”:

Variables

Fetch if any of the nested objects defined via an array relationship satisfy a condition

Example:

Fetch all authors which have written at least one article which is rated 1:

Variables

Fetch if all of the nested objects defined via an array relationship satisfy a condition

By default a row is returned if any of the nested objects satisfy a condition. To achieve the above, we need to frame the where expression as {_not: {inverse-of-condition}}. This reads as: fetch if not (any of the nested objects satisfy the inverted condition) i.e. all of the nested objects satisfy the condition.

For example:

condition where expression
{object: {field: {_eq: "value"}}} {_not: {object: {field: {_neq: "value"}}}
{object: {field: {_gt: "value"}}} {_not: {object: {field: {_lte: "value"}}}

Example:

Fetch all authors which have all of their articles published i.e. have {is_published {_eq: true}.

Variables

Fetch if none of the nested objects defined via an array relationship satisfy a condition

By default a row is returned if any of the nested objects satisfy a condition. To achieve the above, we need to frame the where expression as {_not: {condition}}. This reads as: fetch if not (any of the nested objects satisfy the condition) i.e. none of the nested objects satisy the condition.

For example,

condition where expression
{object: {field: {_eq: "value"}}} {_not: {object: {field: {_eq: "value"}}}
{object: {field: {_gt: "value"}}} {_not: {object: {field: {_gt: "value"}}}

Example:

Fetch all authors which have none of their articles published i.e. have {is_published {_eq: true}:

Variables

Fetch if nested object(s) exist/do not exist

You can filter results based on if they have nested objects by checking if any nested objects exist. This can be achieved by using the expression {} which evaluates to true if any object exists.

Example where nested object(s) exist:

Fetch all authors which have at least one article written by them:

Variables

Example where nested object(s) do not exist:

Fetch all authors which have not written any articles:

Variables

Cast a field to a different type before filtering (_cast)

The _cast operator can be used to cast a field to a different type, which allows type-specific operators to be used on fields that otherwise would not support them. Currently, only casting between PostGIS geometry and geography types is supported.

Casting using _cast corresponds directly to SQL type casts.

Example: cast ``geometry`` to ``geography``

Filtering using _st_d_within over large distances can be inaccurate for location data stored in geometry columns. For accurate queries, cast the field to geography before comparing:

Variables

Example: cast ``geography`` to ``geometry``

Columns of type geography are more accurate, but they don’t support as many operations as geometry. Cast to geometry to use those operations in a filter:

Variables

Note

For performant queries that filter on casted fields, create an expression index on the casted column. For example, if you frequently perform queries on a field location of type geometry casted to type geography, you should create an index like the following:

CREATE INDEX cities_location_geography ON cities USING GIST ((location::geography));

The TRUE expression ( { } )

The expression {} evaluates to true if an object exists (even if it’s null).

For example:

  • any query with the condition { where: {} } will return all objects without applying any filter.
  • any query with the condition { where: { nested_object: {} } } will return all objects for which atleast one nested_object exists.

Evaluation of null values in comparision expressions

If in any comparision expression a null (or undefined) value is passed, the expression currently gets reduced to {} (TRUE expression)

For example, the expression { where: { _eq: null } } will be reduced to { where: {} }