GROQ: Filter by referenced document ID in nested array projection

6 replies
Last updated: Nov 29, 2025
Hey guys. I’ve see a lot of GROQ related questions here recently so apologies if I’m duplicating myself but… is there a way to get a referenced document id to be later used in filter?
I have a nested array for example with different types of objects with references, but when I try to use
references
filter inside it as such I get nothing:

_type == 'contentSubjectTag' => {
  _type,
  "title": subjectTag->title,
  "text": subjectTag->text,
  "subjects": *[_type=='subject' && references(subjectTag->_id)]{
    title,
    externalLink,
  },
},
AI Update

I can see the issue you're encountering. When you try to use references(subjectTag->_id) inside a projection, the dereferencing operation (->) happens in a different context, and you can't directly use it within the references() function like that.

The problem is that subjectTag->_id tries to dereference in the context of the outer document, but inside the nested query *[_type=='subject' && references(...)], you need the actual ID value, not a path expression.

Here are two solutions:

Solution 1: Store the ID in a variable first

_type == 'contentSubjectTag' => {
  _type,
  "title": subjectTag->title,
  "text": subjectTag->text,
  "subjectTagId": subjectTag->_id,
  "subjects": *[_type=='subject' && references(^.subjectTagId)]{
    title,
    externalLink,
  },
},

By first storing subjectTag->_id as "subjectTagId", you create a field in the projected object. Then you can reference it using the parent operator (^) in your nested query.

Solution 2: Use the reference directly

If your subjectTag field is a reference (contains {_ref: "..."} structure), you can use the reference value directly:

_type == 'contentSubjectTag' => {
  _type,
  "title": subjectTag->title,
  "text": subjectTag->text,
  "subjects": *[_type=='subject' && references(^.subjectTag._ref)]{
    title,
    externalLink,
  },
},

Here, ^.subjectTag._ref accesses the _ref property of the reference object in the parent document.

The key insight is that the parent operator ^ lets you access fields from the outer document context when you're inside a nested query. You need to either:

  1. Pre-compute the dereferenced ID as a field, then reference it with ^ (Solution 1)
  2. Access the raw _ref value from the reference object using ^ (Solution 2)

Both approaches work around the limitation that you can't perform dereferencing operations directly inside the references() function parameter. The parent operator ^ is essential here because it allows your nested query to reach back up to the parent document's context and grab the value you need.

Show original thread
6 replies

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?