API Reference - Query / Subscription
query / subscription syntaxβ
query|subscription [<op-name>] {
object [([argument])]{
object-fields
}
}
Key | Required | Schema | Description |
---|---|---|---|
op-name | false | Value | Name query/subscription for observability |
object | true | Object | Name of the table/object |
argument | false | Argument | One 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>
}
Key | Required | Schema | Description |
---|---|---|---|
op-name | false | Value | Name query/subscription for observability |
query-field-name | true | Value | Name 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
..
}
Key | Required | Schema | Description |
---|---|---|---|
path | false | Value | path 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):
Operator | PostgreSQL equivalent |
---|---|
_eq | = |
_neq | <> |
_gt | > |
_lt | < |
_gte | >= |
_lte | <= |
_in | IN |
_nin | NOT IN |
(For more details, refer to the Postgres docs for comparison operators and list based search operators.)
Text related operators:
Operator | PostgreSQL equivalent |
---|---|
_like | LIKE |
_nlike | NOT LIKE |
_ilike | ILIKE |
_nilike | NOT ILIKE |
_similar | SIMILAR TO |
_nsimilar | NOT SIMILAR TO |
_regex | ~ |
_iregex | ~* |
_nregex | !~ |
_niregex | !~* |
(For more details on text related operators, refer to the Postgres docs.)
Checking for NULL values:
Operator | PostgreSQL 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:
Operator | PostgreSQL equivalent |
---|---|
_cast (takes a CastExp as a value) | :: |
(For more details on type casting, refer to the Postgres docs.)
JSONB operators:
Operator | PostgreSQL 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:
Operator | PostGIS equivalent |
---|---|
_st_contains | ST_Contains(column, input) |
_st_crosses | ST_Crosses(column, input) |
_st_equals | ST_Equals(column, input) |
_st_intersects | ST_Intersects(column, input) |
_st_overlaps | ST_Overlaps(column, input) |
_st_touches | ST_Touches(column, input) |
_st_within | ST_Within(column, input) |
_st_d_within | ST_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:
Operator | PostgreSQL equivalent | Input object |
---|---|---|
_st_intersects_rast | ST_Intersects(column, value) | { _st_intersects_rast: raster } |
_st_intersects_nband_geom | ST_Intersects(column, nband, geommin) | { _st_intersects_nband_geom: {nband: Integer! geommin: geometry!} |
_st_intersects_geom_nband | ST_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:
Operator | PostgreSQL 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
andgeography
types - from Postgres
jsonb
type tostring
type.
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
}
}