Graph Query Syntax Reference
CoreGraph
Query structure
Section titled “Query structure”Every Graph query follows this pattern:
query { ContentTypeName( where: { /* filters */ } orderBy: { /* sort */ } limit: 10 cursor: "abc123" locale: en ) { items { /* fields */ } total cursor facets { /* aggregations */ } }}Filtering (where)
Section titled “Filtering (where)”Comparison operators
Section titled “Comparison operators”| Operator | Description | Example |
|---|---|---|
eq | Equals | { Status: { eq: "Published" } } |
notEq | Not equals | { Category: { notEq: "Draft" } } |
gt | Greater than | { Price: { gt: 100 } } |
gte | Greater than or equal | { Rating: { gte: 4 } } |
lt | Less than | { Stock: { lt: 10 } } |
lte | Less than or equal | { Age: { lte: 30 } } |
in | In list | { Category: { in: ["News", "Blog"] } } |
notIn | Not in list | { Status: { notIn: ["Archived"] } } |
like | Pattern match | { Title: { like: "%optimizely%" } } |
startsWith | Prefix match | { Name: { startsWith: "Product" } } |
endsWith | Suffix match | { Email: { endsWith: "@optimizely.com" } } |
contains | Contains substring | { Body: { contains: "getting started" } } |
exist | Has value | { HeroImage: { exist: true } } |
Boolean logic
Section titled “Boolean logic”# AND (default — all conditions must match)where: { Status: { eq: "Published" } Category: { eq: "News" }}
# OR — any condition matcheswhere: { _or: [ { Category: { eq: "News" } } { Category: { eq: "Blog" } } ]}
# NOT — negate a conditionwhere: { _not: { Status: { eq: "Archived" } }}Date filtering
Section titled “Date filtering”where: { _metadata: { published: { gte: "2025-01-01T00:00:00Z" } }}Nested content filtering
Section titled “Nested content filtering”where: { MainContentArea: { ContentLink: { Id: { eq: 42 } } }}Sorting (orderBy)
Section titled “Sorting (orderBy)”# Single fieldorderBy: { PublishedDate: DESC }
# Multiple fieldsorderBy: { Category: ASC, PublishedDate: DESC }
# Sort by metadataorderBy: { _metadata: { published: DESC } }
# Sort by relevance (with search)orderBy: { _ranking: SEMANTIC }| Direction | Description |
|---|---|
ASC | Ascending (A→Z, oldest→newest, lowest→highest) |
DESC | Descending (Z→A, newest→oldest, highest→lowest) |
Pagination
Section titled “Pagination”Cursor-based (recommended)
Section titled “Cursor-based (recommended)”# First pagequery { ArticlePage(limit: 10) { items { Headline } cursor # Pass this to the next query total}}
# Next pagequery { ArticlePage(limit: 10, cursor: "eyJsaW...") { items { Headline } cursor total}}Skip-based
Section titled “Skip-based”query { ArticlePage(limit: 10, skip: 20) { items { Headline } total}}Full-text search
Section titled “Full-text search”query { ArticlePage( where: { _fulltext: { contains: "content modeling" } } orderBy: { _ranking: RELEVANCE } ) { items { Headline _fulltext # Returns matched text with highlights _score # Relevance score } total }}Search options
Section titled “Search options”| Parameter | Description |
|---|---|
contains | Search for terms in any fulltext-indexed field |
match | Exact phrase match |
boost | Boost relevance of specific fields |
synonym | Enable synonym matching |
Facets (aggregations)
Section titled “Facets (aggregations)”query { ArticlePage { facets { Category(limit: 10) { name # Category value count # Number of matching items } PublishedDate(unit: MONTH) { name # Month bucket count } } total }}Facet types
Section titled “Facet types”| Facet | Applies to | Options |
|---|---|---|
| String facet | String properties | limit, orderBy, orderType |
| Date facet | DateTime properties | unit (DAY, WEEK, MONTH, YEAR) |
| Number range | Numeric properties | ranges: [{ from: 0, to: 100 }] |
Metadata fields
Section titled “Metadata fields”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 } } } }}Locale filtering
Section titled “Locale filtering”# Single localequery { ArticlePage(locale: en) { items { Headline } } }
# Multiple localesquery { ArticlePage(locale: [en, sv]) { items { Headline } } }
# All localesquery { ArticlePage(locale: ALL) { items { Headline _metadata { locale } }}}Rate limits and best practices
Section titled “Rate limits and best practices”| Limit | Value |
|---|---|
| Max query depth | 10 levels |
| Max result size | 10,000 items |
| Default limit | 20 items |
| Max limit | 100 items per query |
| Query timeout | 30 seconds |
Best practices:
- Always use
limitto 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
Related
Section titled “Related”- Content Delivery with Graph — Architecture concepts
- Set Up Graph — Configuration guide
- Property Types — CMS to Graph type mappings