Dereferencing nested object references in GROQ array query

5 replies
Last updated: Feb 24, 2021
Ok, this one is complicated. In the content I have "Recipe" with an array of "fresh" ingredients (objects) where the name is a reference to a "Tag" (called: ingredienttag). When I fetch the recipes in React, like:sanityClient
.fetch(

*[_type == "recipe"]{
       _id,
       title,
       slug,
       "dish": dish->{_id, name},
       fresh,
       stock,
       directions,
       "related": related[]->{title},
       "book": book->{_id, name, author},
       info,
       "tag": tag[]->{_id, name, category->{_id, name}},
      }
)
it returns the complete fresh array including <quantity, unit, ingredienttag: {_ref: "5f3bdac9e6490b05c8ba48ae", _type: "reference"}>.
Obviously I want to return the name of the referenced "tag", instead of _ref.
So instead of <fresh,> I do < "fresh": fresh[]->{quantity, unit, ingredienttag->{name}},> but it just returns an array of empty objects.
What can be wrong here? (all the rest is working as expected)
AI Update

The issue you're encountering is a common GROQ gotcha! The problem is that you're trying to dereference the fresh array itself with fresh[]->, but fresh isn't an array of references - it's an array of objects that contain a reference field (ingredienttag).

The -> dereferencing operator only works directly on reference fields, not on objects that contain references. When you use fresh[]->, GROQ tries to dereference each object in the array (not the reference inside it), which fails and returns empty objects.

Here's the solution - you need to project the array without dereferencing it, then dereference the nested reference field:

*[_type == "recipe"]{
  _id,
  title,
  slug,
  "dish": dish->{_id, name},
  "fresh": fresh[]{
    quantity,
    unit,
    "ingredienttag": ingredienttag->{name}
  },
  stock,
  directions,
  "related": related[]->{title},
  "book": book->{_id, name, author},
  info,
  "tag": tag[]->{_id, name, category->{_id, name}}
}

The key difference: use fresh[]{} (array projection) instead of fresh[]-> (array dereferencing). Inside the projection {}, you can then dereference the ingredienttag reference field with ingredienttag->{name}.

Why this works:

  • fresh[] iterates over the array elements
  • {quantity, unit, "ingredienttag": ingredienttag->{name}} projects each object, keeping quantity and unit, and dereferencing the ingredienttag reference to get its name

This pattern applies whenever you have an array of objects containing references - project the array first with []{}, then dereference the reference fields inside the projection. You can see this pattern in your working queries like "tag": tag[]->{_id, name, category->{_id, name}} where references are dereferenced, but that works because tag is an array of references directly, not an array of objects containing references.

As covered in the GROQ projections documentation, projections let you reshape data and follow references, but the syntax matters depending on your document structure!

Show original thread
5 replies
Hi Pieter. It looks like the
fresh[]
array doesn't contain any references, but a direct application of ingredienttag. If that's how you want it to be, you could try removing the dereferencing operator (
->
) after
fresh[]
to see if that works.
Thanks, but please read carefully. I did "fresh": fresh[]->{quantity, unit, ingredienttag->{name}}, as I mentioned before, but it just returns an array of empty objects. These are the 3 different results:fetch1 = fresh,
console1 = fresh: 0
:ingredienttag: {_ref: "5f3bdac9e6490b05c8ba48ae", _type: "reference"}fetch2 = "fresh": fresh[]->,
console2 = fresh: Array(2) 0: null 1: null
fetch3 ="fresh": fresh[]->{ingredient, quantity, unit, ingredienttag->{name}},
console3 = fresh: Array(2) 0: {} 1: {}
Nothing works to get the name of "ingredienttag".
I am getting the same problem following the "Minimal Example" at Sanity. I want to fetch an array of crewMembers, with their jobs and names together. I tried: "crewMembers": crewMembers[]->{job, person->name}, but this does not work. What is the correct query?
Thanks, but please read carefully. I did “fresh”: fresh[]->{quantity, unit, ingredienttag->{name}}, as I mentioned before
Please accept my apologies, Pieter. What I haven’t yet seen you try in those three examples is removing the dereferencing operator,
->
, after
fresh[]
(in your first fetch example it’s removed, but only after
fresh
). Since
fresh[]
is an array of type
ingredienttag
and not an array of references, I don’t expect you’d want to include it.
I created a prototype of your schema and this worked for me:


*[_type == "recipe"] {
  _id,
  title,
  slug,
  "fresh": fresh[] {
    quantity,
    unit,
    ingredienttag->{name}
  }
}
Hey Geoff, 1000x thanks! You saved my day.

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?