A tutorial on using the Sanity query language GROQ.
The idea behind our query language GROQ (Graph-Relational Object Queries) is to be able to describe exactly what information your application needs, potentially joining together information from several sets of documents, then stitching together a very specific response with only the exact fields you need.
If you need help setting up a client to perform these queries in your front end, you should check out the documentation for the client for JavaScript or PHP. You can also check out the GROQ Arcade if you want to query any JSON source and get familiar with the language.
Introduction
Let us start with the basics. We will take this simple query and pick it apart:
*[_type == 'movie' && releaseYear >= 1979]
A query typically starts with *. This asterisk represents every document in your dataset. To do any useful work this is typically followed by a filter in brackets. The filter above has two terms:
The filter
First, we filter by document type. Every document in Sanity is required to have a type, and the type is always in the _type field. (We prefix any Sanity-specific fields with an underscore in an attempt to avoid clashing with any of your field names.) So _type == 'movie' limits this query to documents of the type ‘movie’. && is the operator “and”.
The second term releaseYear >= 1979 assumes that the movies have a field called releaseYear that contains numbers. It will match any document where this number is larger than or equal to 1979.
Projections
So if we run this query, the result will be an array containing all movies from the year 1979 onwards in the dataset. Nice! However in a typical application movies might be huge documents containing information on actors, staff, posters, tag-lines, show-times, ratings, and whatnot. If our goal is to render a list of movies in an overview, we are wasting bandwidth. Projections to the rescue.
The typical projection is wrapped in braces and describes the data we want to see for each movie. A nice and simple projection for this query would give us the id, title, and release year for each movie. It could look like this: {_id, title, releaseYear}. Putting it all together:
*[_type == 'movie' && releaseYear >= 1979]{ _id, title, releaseYear }
Slicing the result set
This brings us to our final problem for this query: There are many movies in the world. Maybe our dataset contains tens of thousands. We need a way to describe which slice of that list we want to show. This is done using a selector. Let’s say we just wanted the first movie, we could add a [0] at the end. This works exactly like an array accessor and would return only the first element. If we want a slice, we can add the range operator like this: [0...100]. This would return the first hundred movies from index 0 through 99. We can just as well ask for [1023...1048] or any other slice we desire. So there we are, our first basic query with filtering, ordering, projections, and selector:
*[_type == 'movie' && releaseYear >= 1979] | order(releaseYear) {
_id, title, releaseYear
}[0...100]
References and joins
A reference in Sanity is a link from one document to another. Standard references are “hard” meaning when a document references another document, the target document must exist, and is actually prevented from being deleted until the reference is removed. (There are also weak-references that do not "hold on to" the target. You make them by adding a _weak-key to the reference object like this: {_ref: "<document-id>", _weak: true})
Let’s say we have “person”-type documents that looks something like this:
{
_id: "ridley-scott",
_type: "person",
name: "Ridley Scott"
}
Finally
So there you go, this should cover most of what you need to understand in the day-to-day use of GROQ. You should now check out our Query Cheat Sheet, the GROQ Arcade, and the reference docs which contain examples of all operators and functions currently supported.
Comments