Skip to content

Graph Query Syntax Reference

intermediate
📜CoreGraph

Every Graph query follows this pattern:

query {
ContentTypeName(
where: { /* filters */ }
orderBy: { /* sort */ }
limit: 10
cursor: "abc123"
locale: en
) {
items { /* fields */ }
total
cursor
facets { /* aggregations */ }
}
}
OperatorDescriptionExample
eqEquals{ Status: { eq: "Published" } }
notEqNot equals{ Category: { notEq: "Draft" } }
gtGreater than{ Price: { gt: 100 } }
gteGreater than or equal{ Rating: { gte: 4 } }
ltLess than{ Stock: { lt: 10 } }
lteLess than or equal{ Age: { lte: 30 } }
inIn list{ Category: { in: ["News", "Blog"] } }
notInNot in list{ Status: { notIn: ["Archived"] } }
likePattern match{ Title: { like: "%optimizely%" } }
startsWithPrefix match{ Name: { startsWith: "Product" } }
endsWithSuffix match{ Email: { endsWith: "@optimizely.com" } }
containsContains substring{ Body: { contains: "getting started" } }
existHas value{ HeroImage: { exist: true } }
# AND (default — all conditions must match)
where: {
Status: { eq: "Published" }
Category: { eq: "News" }
}
# OR — any condition matches
where: {
_or: [
{ Category: { eq: "News" } }
{ Category: { eq: "Blog" } }
]
}
# NOT — negate a condition
where: {
_not: { Status: { eq: "Archived" } }
}
where: {
_metadata: {
published: { gte: "2025-01-01T00:00:00Z" }
}
}
where: {
MainContentArea: {
ContentLink: {
Id: { eq: 42 }
}
}
}
# Single field
orderBy: { PublishedDate: DESC }
# Multiple fields
orderBy: { Category: ASC, PublishedDate: DESC }
# Sort by metadata
orderBy: { _metadata: { published: DESC } }
# Sort by relevance (with search)
orderBy: { _ranking: SEMANTIC }
DirectionDescription
ASCAscending (A→Z, oldest→newest, lowest→highest)
DESCDescending (Z→A, newest→oldest, highest→lowest)
# First page
query { ArticlePage(limit: 10) {
items { Headline }
cursor # Pass this to the next query
total
}}
# Next page
query { ArticlePage(limit: 10, cursor: "eyJsaW...") {
items { Headline }
cursor
total
}}
query { ArticlePage(limit: 10, skip: 20) {
items { Headline }
total
}}
query {
ArticlePage(
where: { _fulltext: { contains: "content modeling" } }
orderBy: { _ranking: RELEVANCE }
) {
items {
Headline
_fulltext # Returns matched text with highlights
_score # Relevance score
}
total
}
}
ParameterDescription
containsSearch for terms in any fulltext-indexed field
matchExact phrase match
boostBoost relevance of specific fields
synonymEnable synonym matching
query {
ArticlePage {
facets {
Category(limit: 10) {
name # Category value
count # Number of matching items
}
PublishedDate(unit: MONTH) {
name # Month bucket
count
}
}
total
}
}
FacetApplies toOptions
String facetString propertieslimit, orderBy, orderType
Date facetDateTime propertiesunit (DAY, WEEK, MONTH, YEAR)
Number rangeNumeric propertiesranges: [{ from: 0, to: 100 }]

Every content item has a _metadata field with system properties:

query {
ArticlePage {
items {
_metadata {
key # Content GUID
locale # Language code
published # Publish date
status # Published, Draft, etc.
types # Content type names
url {
default # Primary URL
internal # CMS internal URL
}
}
}
}
}
# Single locale
query { ArticlePage(locale: en) { items { Headline } } }
# Multiple locales
query { ArticlePage(locale: [en, sv]) { items { Headline } } }
# All locales
query { ArticlePage(locale: ALL) {
items {
Headline
_metadata { locale }
}
}}
LimitValue
Max query depth10 levels
Max result size10,000 items
Default limit20 items
Max limit100 items per query
Query timeout30 seconds

Best practices:

  • Always use limit to control result size
  • Use cursor pagination for large datasets (skip-based is slower beyond 1000 items)
  • Filter server-side — do not fetch all items and filter in the frontend
  • Use facets for filter counts instead of separate queries