API Reference - Query / Subscription¶
Table of contents
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¶
SimpleObject | AggregateObject
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 | WhereExp | OrderByExp | PaginationExp
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 | OrExp | NotExp | TrueExp | ColumnExp
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 casting between geometry
and geography
types is allowed.
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
.
{column: OrderByEnum}
PaginationExp¶
limit: Integer
[offset: Integer]
Example
query {
article(limit: 6, offset: 2) {
title
content
}
}