Querying references and displaying them in Sanity Studio.

11 replies
Last updated: Aug 24, 2023
Do references store any parent data and if so how do i query it in groq ?
AI Update

No, references in Sanity do not store parent data - they only store the ID of the referenced document in a _ref field. A reference is essentially just a pointer to another document.

For example, when you have a reference field, it's stored like this:

{
  "_id": "alice",
  "_type": "employee",
  "name": "Alice Anderson",
  "department": {"_ref": "engineering"}
}

Notice that department only contains {"_ref": "engineering"} - no actual department data is stored in the parent document.

Querying References with GROQ

To retrieve the actual referenced document data, you use the dereference operator -> in GROQ:

*[_type == "employee"] {
  name,
  department->
}

This resolves the reference and returns the full department document:

{
  "name": "Alice Anderson",
  "department": {
    "_id": "engineering",
    "_type": "department",
    "name": "Engineering"
  }
}

You can also project specific fields from the referenced document:

*[_type == "employee"] {
  name,
  department->{
    name,
    location
  }
}

Array References

For arrays of references, dereference all items like this:

*[_type == "footer"] {
  socials[]->{
    name,
    url
  }
}

Reverse Lookups

If you need to find documents that reference a specific document (reverse lookup), use the references() function:

*[_type == "artist"][0] {
  name,
  "events": *[_type == "event" && references(^._id)] {
    name
  }
}

This finds all events that reference the current artist.

The key takeaway: references are lightweight pointers that only store IDs, and you use the -> operator to fetch the actual referenced document data when querying.

Can you clarify what you mean by parent data? An example to illustrate what you are trying to achieve would be helpful.
Of course! I have two documents, "Location Tags" and "Locations" i would like to add "Location Tags" to "Locations" and the reverse. However i am struggling with the schema. I created 3 separate "Location Tags" and i was able to reference them in "Locations" using this schema snippet:
{
  name: 'tags',
  title: 'Location Tags',
  type: 'array',
  of: [{ type: 'reference', to: { type: 'locationTag' }}],
},
This works fine, how ever there is no reference to these "Locations" when i look at the "Location Tags" in Sanity Studio. So i added a reference to "Locations" in the "Location Tag" document schema. Essential the reverse with this snippet:
{
  name: 'associatedLocation',
  title: 'Associated Locations',
  type: 'array',
  of: [{ type: 'reference', to: { type: 'location' } }],
},
When querying "Locations i get the location information but not the reference data.
"tags": *[_type == "locationTag" && references(^._id)]{
    "id": _id,
    "createdAt": _createdAt,
    name,
    "slug": slug.current,
    description
},
Thanks for sharing additional information πŸ‘References are are
bi-directional by default and can be queried from either side of their relationship so you need not add the
associatedLocation
bit.So if you want to get all locations by tag, you can query them like so:

*[_type == 'locationTag']{
  'locations': *[_type == 'location' && references(^._id)]{
    ...,
  }
}
If you want to get all tags by location, then you can query them as well like so:

*[_type == 'location']{
  'tags': tags[]->,
  ...,
  }
}
Thank you! I have been wracking my brain all day.
user F
last thing though, should these reference not also show up as UI elements in Sanity Studio? Currently my "location tag" document show no visual reference to it's relationship with "locations"
It will only show up in the "locations" document which is referencing these tags and not the other way round.
ok, and is there anything i can do to display this reference or is that just the way it work?
If a document was referenced in many different places then showing this in the UI would become unruly very quickly, so I presume this is the default behaviour that was chosen.If you do need to show it then you can try the method that you were experimenting with earlier to explicitly add a reverse reference I suppose.
The other option perhaps would be to build your own
Custom component which renders this list of locations for each tag.
Thank you, it's no the end of the world just needed clarification that it was "as designed" and not a bug in my own code. Have a great day and thank you again πŸ™‚

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?