Sanity
Learn (Beta)
Course

Day One with Sanity Studio

Lesson
7

A taste of GROQ

GROQ is a query language for JSON data. Learn just enough to query your content.

Log in to mark your progress for each Lesson and Task

While Sanity also has a GraphQL API, most choose to query their Sanity content using GROQ.

While you can think of GraphQL as a replacement for RESTful APIs, GROQ is more like SQL for JSON. In other words, you can do way more with it.

GROQ is also used for configuring parts of the Studio configuration API and project-level features like GROQ-powered webhooks, and user access control.

Learn more about GROQ and GraphQL in the documentation.

The Vision tool lets you run queries against your project's dataset(s) from Sanity Studio. It comes preinstalled with new studios. In the Studio's toolbar, next to Structure, select Vision.

To start with, you can think of a GROQ expression as three parts.

Consider this query:

*[_type == "event"]{title}
  • *: Represents all documents in a dataset as an array
  • [_type == "event"] represents a filter where you narrow down those documents
  • { title } represents a projection where you define which attribute in those matching documents you want the query to return
See Query Language (GROQ) in the documentation.
Write your first GROQ query for all documents:
*

The * indicates you want to return every document in the target dataset, which will be returned in an array.

You can add a set of [] square brackets with a logical expression in them – called a filter – to return only a subset of the documents within it.

Filter the array to just our "event" documents:
*[_type == "event"]

You can stack filters for even more granular results and, to a small extent, faster responses.

Perhaps you only want to return event documents that are marked as in-person. Yes, you can filter on any key and value that your documents might have.

Write a query just for in-person events
*[
_type == "event"
&& eventType == "in-person"
]

In the previous lesson, you may have also noticed a GROQ filter in the Structure builder configuration to list out future and past events.

You could use the now() function here to only return upcoming in-person events

Write a query just for upcoming in-person events
*[
_type == "event"
&& eventType == "in-person"
&& date > now()
]
See the documentation about Functions

Currently, every field in every returned document is being returned. This is more data than we need! Over-fetching can lead to slower queries and makes it less clear to others which attributes your application depends on.

Add a projection {} after the array filter so that for every item in the array, only certain attributes are returned.

Add a projection to return only the event name and the artist name
*[
_type == "event"
&& eventType == "in-person"
&& date > now()
]{
name,
headline->{
name
},
"isUpcoming": true
}

In this projection, you are doing the following:

  • Returning the event's name as-is
  • Using the -> to join the referenced artist document for headline and return just the name of that artist (try removing the arrow and the projection after to see the difference in the returned data)
  • Defining some arbitrary data for isUpcoming (which is implied by the filter), demonstrating the flexibility of GROQ by creating and returning new content in the context of a query.

This is just the beginning, but it's enough for us to query Sanity content and render it in an application.

See Query Cheat Sheet - GROQ for more GROQ examples.
To learn more consider taking the Between GROQ and a hard place module.