Skip to main content
Version: v2.x

API Reference - Query / Subscription

query / subscription syntax

query|subscription [<op-name>] {
object [([argument])]{
object-fields
}
}
KeyRequiredSchemaDescription
op-namefalseValueName query/subscription for observability
objecttrueObjectName of the table/object
argumentfalseArgumentOne or more of filter criteria, instructions for sort order or pagination

Example: Query

query {
author(where: { articles: { rating: { _gte: 4 } } }, order_by: { name: asc }) {
id
name
}
}

Example: Subscription

subscription {
author(where: {articles: rating: {_gte: 4}}} order_by: {name: asc}) {
id
name
}
}
Note

For more examples and details of usage, please see this.

query_by_pk / subscription_by_pk syntax

query|subscription [<op-name>] {
<query-field-name> (
column1: value1
column2: value2
)
<object-fields>
}
KeyRequiredSchemaDescription
op-namefalseValueName query/subscription for observability
query-field-nametrueValueName of the auto-generated query field, e.g. article_by_pk

Example: Query by PK

query {
article_by_pk(id: 1) {
id
title
}
}

Example: Subscription by PK

subscription {
article_by_pk(id: 1) {
id
title
}
}

Syntax definitions

Object

Simple object

object-name {
field1
field2
json_field[(path: String)]
..
nested object1
nested object2
aggregate nested object1
..
}
KeyRequiredSchemaDescription
pathfalseValuepath argument of json/jsonb follows simple JSONPath specification. However, prefix symbol $. is optional.

Example

author {
id # scalar integer field

name # scalar text field

address(path: "$.city") # scalar JSON field -> property
address(path: "$.city.altitude") # scalar JSON field -> property -> property
address(path: "city") # scalar JSON field -> property; '$.' prefix is optional
contacts(path: "[0]") # scalar JSON field -> array_item
contacts(path: "[0].phone") # scalar JSON field -> array_item_property
contacts(path: "['Hello world!']") # scalar JSON field -> property; used for special characters key
contacts(path: "[\"Hello world!\"]") # same as above; the syntax is ugly, but still works

article { # nested object
title
}

article_aggregate { # aggregate nested object
aggregate {
count
}
nodes {
title
}
}
}

Aggregate object

object-name_aggregate {
aggregate {
count
sum {
field
..
}
avg {
field
..
}
stddev {
field
..
}
stddev_samp {
field
..
}
stddev_pop {
field
..
}
variance {
field
..
}
var_samp {
field
..
}
var_pop {
field
..
}
max {
field
..
}
min {
field
..
}
nodes {
field1
field2
..
nested object1
nested object2
aggregate nested object1
..
}
}

(For more details on aggregate functions, refer to the Postgres docs).

Example

author_aggregate {
aggregate {
count # total count
sum {
id # sum aggregate on id
}
avg {
id # avg aggregate on id
}
stddev {
id # stddev aggregate on id
}
stddev_samp {
id # stddev_samp aggregate on id
}
stddev_pop {
id # stddev_pop aggregate on id
}
variance {
id # variance aggregate on id
}
var_samp {
id # var_samp aggregate on id
}
var_pop {
id # var_pop aggregate on id
}
max {
id # max aggregate on id
}
min {
id # min aggregate on id
}
}

nodes { # objects
id # scalar field
name # scalar field

article { # nested object
title
}

article_aggregate { # aggregate nested object
aggregate {
count
}
nodes {
title
}
}
}
}

Argument

DistinctOnExp

distinct_on: [TableSelectColumnEnum]

Example

query {
article(distinct_on: title) {
title
content
}
}
TableSelectColumnEnum
#example table_select_column enum for "article" table
enum article_select_column {
id
title
content
author_id
is_published
}

WhereExp

where: BoolExp

Example

query {
author(where: { rating: { _gt: 4 } }) {
name
articles {
title
}
}
}
BoolExp
AndExp
{
  _and: [BoolExp]
}

Example

query {
article(where: { _and: [{ rating: { _gt: 4 } }, { published_on: { _gt: "2018-01-01" } }] }) {
title
content
}
}
Syntactic sugar

You can simplify an _and expression by passing the sub-expressions separated by a ,.

First example: _and expression with different fields

{
_and: [
{ rating: { _gte: 4 } },
{ published_on: { _gte: "2018-01-01" } }
]
}

# can be simplified to:

{
rating: { _gte: 4 },
published_on: { _gte: "2018-01-01" }
}

Second example: _and expression with same field

_and: [
{
rating: {
_gt: 1
}
},
{
rating: {
_lt: 5
}
}
]

# can be simplified to:

rating: {
_gt: 1,
_lt: 5
}
OrExp
{
  _or: [BoolExp]
}

Example

query {
article(where: { _or: [{ rating: { _gt: 4 } }, { is_published: { _eq: true } }] }) {
title
content
}
}
Note

The _or operator expects an array of expressions as input. Passing an object to it will result in the behaviour of the _and operator due to the way GraphQL list input coercion behaves.

Example:

{
_or: {
rating: { _gte: 4 },
published_on: { _gte: "2018-01-01" }
}
}

# will be coerced to:

{
_or: [
{
rating: { _gte: 4 },
published_on: { _gte: "2018-01-01" }
}
]
}

# which is equivalent to:

{
_or: [
_and: [
{ rating: { _gte: 4 } },
{ published_on: { _gte: "2018-01-01" } }
]
]
}
NotExp
{
  _not: BoolExp
}

Example

query {
article(where: { _not: { title: { _eq: "" } } }) {
title
content
}
}
TrueExp
{}

Example

query {
author(where: { articles: {} }) {
name
}
}
Note

{} evaluates to true whenever an object exists (even if it's null).

ColumnExp
{
  field-name: { Operator: Value }
}

Example

query {
article(where: { title: { _eq: "GraphQL Tutorial" } }) {
title
content
}
}
Operator

Generic operators (all column types except json, jsonb):

OperatorPostgreSQL equivalent
_eq=
_neq<>
_gt>
_lt<
_gte>=
_lte<=
_inIN
_ninNOT IN

(For more details, refer to the Postgres docs for comparison operators and list based search operators.)

Text related operators:

OperatorPostgreSQL equivalent
_likeLIKE
_nlikeNOT LIKE
_ilikeILIKE
_nilikeNOT ILIKE
_similarSIMILAR TO
_nsimilarNOT SIMILAR TO
_regex~
_iregex~*
_nregex!~
_niregex!~*

(For more details on text related operators, refer to the Postgres docs.)

Checking for NULL values:

OperatorPostgreSQL equivalent
_is_null (takes true/false as values)IS NULL

(For more details on the IS NULL expression, refer to the Postgres docs.)

Type casting:

OperatorPostgreSQL equivalent
_cast (takes a CastExp as a value)::

(For more details on type casting, refer to the Postgres docs.)

JSONB operators:

OperatorPostgreSQL equivalent
_contains@>
_contained_in<@
_has_key?
_has_keys_any?!
_has_keys_all?&

(For more details on JSONB operators, refer to the Postgres docs.)

PostGIS related operators on GEOMETRY columns:

OperatorPostGIS equivalent
_st_containsST_Contains(column, input)
_st_crossesST_Crosses(column, input)
_st_equalsST_Equals(column, input)
_st_intersectsST_Intersects(column, input)
_st_overlapsST_Overlaps(column, input)
_st_touchesST_Touches(column, input)
_st_withinST_Within(column, input)
_st_d_withinST_DWithin(column, input)

(For more details on spatial relationship operators, refer to the PostGIS docs.)

Note
  • All operators take a JSON representation of geometry/geography values as input value.

  • The input value for _st_d_within operator is an object:

    {
    field-name : {_st_d_within: {distance: Float, from: Value} }
    }

Intersect Operators on RASTER columns:

OperatorPostgreSQL equivalentInput object
_st_intersects_rastST_Intersects(column, value){ _st_intersects_rast: raster }
_st_intersects_nband_geomST_Intersects(column, nband, geommin){ _st_intersects_nband_geom: {nband: Integer! geommin: geometry!}
_st_intersects_geom_nbandST_Intersects(column, geommin, nband){ _st_intersects_geom_nband: {geommin: geometry! nband: Integer }

(For more details on intersect operators on raster columns refer to the PostGIS docs.)

ltree operators:

OperatorPostgreSQL equivalent
_ancestor@>
_ancestor_any@>
_descendant<@
_descendant_any<@
_matches~
_matches_any?
_matches_fulltext@

(For more details on operators on ltree columns refer to the Postgres docs.)

CastExp
{ type-name: {Operator: Value} }

Example

query MyQuery($coordinate: geography!) {
postgis_test_table(
where: {
geometry_column: {
_cast: {
geography: { _st_d_within: { distance: 1000000, from: $coordinate } }
}
}
}
) {
id
}
}

Variables:
{
"coordinate": {
"type": "Point",
"coordinates": [ 2.5559, 49.0083 ]
}
}
Note

Currently, only the following type casts are supported:

  • between PostGIS geometry and geography types
  • from Postgres jsonb type to string type.
AggregationExp
{
  field-name_aggregate: { AggregationPredicate }
}

Note that each field-name_aggregate object may refer to only one aggregation predicate. Multiple aggregation predicates can be specified via the _and operator, however.

Example

query {
restaurant ( where: {
reviews_aggregate: {
average: {
arguments: "rating",
predicate: { _gt: 5 }
}
}
})
{
name
}

AggregationPredicate

function-name: {
    arguments: (column-name | [column-name] | { argument-name: column-name })
    distinct: true | false
    filter:  BoolExp 
    predicate:  Operator 
  }

Aggregation functions may differ in the arguments that they support. For instance, count may take an arbitrary number of arguments, while sum takes exactly one. Certain functions take named arguments.

The functions supported are specific to each backend.

Examples

  average: {
arguments: "rating",
predicate: { _gt: 5 }
}
  count: {
arguments: []
predicate: { _gt: 10 }
}
  count: {
arguments: ["name", "id"]
predicate: { _gt: 10 }
}
  corr: {
arguments: { X: "age", Y: "score" }
predicate: { _gt: 0.6 }
}

OrderByExp

order_by: (TableOrderBy | [TableOrderBy])

Example 1

query {
author(order_by: { rating: desc }) {
name
rating
}
}

Example 2

query {
article(order_by: [{ id: desc }, { author: { id: asc } }]) {
title
rating
}
}

Example 3

query {
article(order_by: [{ id: desc }, { author: { id: asc } }]) {
title
rating
}
}
TableOrderBy

For columns

{ column: OrderByEnum }

Example

query {
article(order_by: { rating: asc }) {
title
content
}
}

For object relations

{ relation-name: TableOrderBy }

Example

query {
article(order_by: { author: { rating: desc } }) {
title
content
}
}

For array relations aggregate

{ relation-name_aggregate: AggregateOrderBy }

Example

query {
author(order_by: { articles_aggregate: { max: { rating: asc } } }) {
name
}
}

For computed fields

Returning scalar values:

{ computed-field-name: OrderByEnum }

Returning set of table rows:

{ computed-field-name: TableOrderBy }
{ computed-field-name_aggregate: AggregateOrderBy }

Order by type for article table:

input article_order_by {
id: order_by
title: order_by
content: order_by
author_id: order_by
#order by using "author" object relationship columns
author: author_order_by
#order by using "likes" array relationship aggregates
likes_aggregate: likes_aggregate_order_by
}

For computed fields returning scalar type

{ computed-field-name: OrderByEnum }

Example

Consider a table student contains integer columns for course subjects to store marks. A computed field with the name total_marks defined to calculate sum of all subject marks. We need to fetch student rows sorted by total_marks.

query {
student(order_by: { total_marks: desc }) {
id
name
total_marks
}
}

For computed fields returning table row type

Computed fields returning set of table rows can be used to sort the query by their aggregate fields.

{ computed-field-name_aggregate: AggregateOrderBy }

Example

A computed field get_articles is defined on the author table which returns set of article table rows. Fetch authors sorted by the count of their articles.

query {
author(order_by: { get_articles_aggregate: { count: desc } }) {
id
name
get_articles {
id
title
content
}
}
}
OrderByEnum
#the order_by enum type
enum order_by {
#in the ascending order, nulls last
asc
#in the ascending order, nulls last
asc_nulls_last
#in the ascending order, nulls first
asc_nulls_first
#in the descending order, nulls first
desc
#in the descending order, nulls first
desc_nulls_first
#in the descending order, nulls last
desc_nulls_last
}
AggregateOrderBy

Count aggregate

{ count: OrderByEnum }

Example

query {
author(order_by: { articles_aggregate: { count: desc } }) {
name
}
}

Operation aggregate

{ op_name: TableAggOpOrderBy }

Example

query {
author(order_by: { articles_aggregate: { sum: { id: desc } } }) {
id
}
}

Available operations are sum, avg, max, min, stddev, stddev_samp, stddev_pop, variance, var_samp and var_pop.

TableAggOpOrderBy
{ column: OrderByEnum }

PaginationExp

limit: Integer
[offset: Integer]

Example

query {
article(limit: 6, offset: 2) {
title
content
}
}