Skip to content

Latest commit

 

History

History
476 lines (364 loc) · 10.3 KB

cheat-sheet.md

File metadata and controls

476 lines (364 loc) · 10.3 KB

Query Cheat Sheet - GROQ

Data query examples from Sanity.io docs.

Given a schema defined as follows, here is how you would replicate these queries using the query builder:

import { defineDocument } from 'sanity-typed-queries'

// This object is the type of the person document for use in the below builder
const { person } = defineDocument('person', {
  name: {
    type: 'string'
  }
})

const { builder: movie } = defineDocument('movie', {
  title: {
    type: 'string'
  },
  priority: {
    type: 'number'
  },
  castMembers: {
    type: 'array',
    of: [
      {
        type: 'reference',
        to: [{ type: 'person' }],
      }
    ]
  },
}, [person])

Constraints

Coming soon.

Slice Operations

  • a single item (an object is returned, not an array)

    *[_type == "movie"][0]
    
    const [query] = movie.first().use()
  • first 6 items (inclusive)

    *[_type == "movie"][0..5]
    
    const [query] = movie.select(0, 5).use()
  • first 5 items (non-inclusive)

    *[_type == "movie"][0...5]
    
    const [query] = movie.select(0, 5, true).use()
  • first 10 item titles

    *[_type == "movie"]{title}[0...10]
    
    const [query] = movie.pick(['title']).select(0, 10, true).use()
  • first 10 item titles

    *[_type == "movie"][0...10]{title}
    
    const [query] = movie.pick(['title']).select(0, 10, true).use()
  • first 10 item titles, offset by 10

    *[_type == "movie"][10...20]{title}
    
    const [query] = movie.pick(['title']).select(10, 20, true).use()
  • no slice specified -> all items are returned

    *[_type == "movie"]
    
    const [query] = movie.use()

Ordering

  • order results

     *[_type == "movie"] | order(_createdAt asc)
    
    const [query] = movie.orderBy('_createdAt').use()
  • order todo items by descending priority, where priority is equal, list most recently updated item first

    *[_type == "movie"] | order(priority desc, _updatedAt desc)
    
    const [query] = movie
      .orderBy('releaseDate', 'desc')
      .orderBy('_createdAt', 'desc')
      .use()
  • the single, oldest document

    *[_type == "movie"] | order(_createdAt asc) [0]
    
    const [query] = movie.orderBy('_createdAt').first().use()
  • the single, newest document

    *[_type == "movie"] | order(_createdAt desc) [0]
    
    const [query] = movie.orderBy('_createdAt', 'desc').first().use()
  • oldest 10 documents

    *[_type == "movie"] | order(_createdAt asc) [0..9]
    
    const [query] = movie.orderBy('_createdAt').select(0, 9).use()

Joins

  • fetch document with title and a custom map

    Say castMembers is an array containing objects with character name and a reference to the person: We want to fetch movie with title and an attribute named "cast" which is an array of actor names

    *[_type=='movie']{title,'cast': castMembers[].person->name}
    
    const [query] = movie
      .map(h => ({ cast: h.castMembers.pick('person').resolve('name').use() }))
      .pick(['title', 'cast'])
      .use()

    Same query as above, except "cast" now contains objects with person._id and person.name

    *[_type=='movie']{title,'cast': castMembers[].person->{_id, name}}
    
    const [query] = movie
      .map(h => ({
        cast: h.castMembers.pick('person').resolve(['_id', 'name']).use(),
      }))
      .pick(['title', 'cast'])
      .use()

Object Projections

  • return only title

    *[_type == 'movie']{title}
    
    const [query] = movie.pick(['title']).use()
  • return values for multiple attributes

    *[_type == 'movie']{_id, _type, title}
    
    const [query] = movie.pick(['_id', '_type', 'title']).use()
  • explicitly name the return field for _id

    *[_type == 'movie']{'renamedId': _id, _type, title}
    
    const [query] = movie
      .map(h => ({ renamedId: h._id.use() }))
      .pick(['renamedId', '_type', 'title'])
      .use()
  • Return an array of attribute values (no object wrapper)

    *[_type == 'movie'].title
    *[_type == 'movie']{'characterNames': castMembers[].characterName}
    
    const [query] = movie.pick('title').use()
    const [secondQuery] = movie
      .map(h => ({ characterNames: h.castMembers.pick('characterName').use() }))
      .pick(['characterNames'])
      .use()
  • Some computed attributes, then also add all attributes of the result

    *[_type == 'movie']{'posterUrl': poster.asset->url, ...}
    
    const [query] = movie
      .map(h => ({ posterUrl: h.poster.asset.resolve('url').use() }))
      .use()
  • Default values when missing or null in document

    *[_type == 'movie']{..., 'rating': coalesce(rating, 'unknown')}
    
    const [query] = movie.map(h => ({ rating: h.rating.use('unknown') })).use()
  • Number of elements in array 'actors' on each movie

    *[_type == 'movie']{"actorCount": count(actors)}
    
    const [query] = movie
      .map(h => ({ actorCount: h.actors.count() }))
      .pick(['actorCount'])
      .use()

Special variables

Coming soon.

Conditionals

Coming soon.

Functions

Coming soon.

Arithmetic and Concatenation

Coming soon.