Joins and subqueries

Try querying for an event document and return the venue reference.
venue
of every event
*[_type == "event" && defined(venue)][0]{ venue}
The venue attribute will return a reference to another document's ID in the attribute _ref
.
You can “resolve” this reference with this operator ->
This deceptively simple operator will perform a “sub-query” to resolve the document with that _id
.
venue
reference*[_type == "event" && defined(venue)][0]{ venue->}
Excellent! We now have the actual details of the category document. But again, we have the “too much data” problem. This can be fixed by adding an additional projection.
name
of the venue
document*[_type == "event" && defined(venue)][0]{ venue->{ name }}
It’s possible to create your own subquery anywhere in a document. However, you should be mindful that additional nesting and queries can increase response time and the volume of data. Exercise caution.
References are one-way in that they are stored on a document. However the references()
GROQ function allows you to look up all other references to a document ID.
A useful sub-query for this project would be to look up every event when querying for an artist, like a reverse lookup of references.
references()
GROQ function, get every event
featuring the current artist
.*[_type == "artist"][0]{ name, "events": *[_type == "event" && references(^._id)]{ name }}
The ^
character traverses out of the current filter to access the "parent." In the above example, it is accessing the _id
attribute of the artist document.