Querying an array of references and getting both the resolved reference and the _key field.

13 replies
Last updated: Sep 26, 2023
Hi all! When i'm querying an array of references, is there any way to get BOTH the resolved reference and the _key field?When I do this:

products[]
I get the unresolved references with their _key, _ref fields etc.
When I do:
products[]->
, I get the resolved references, without the _key field.I need the _key to have a unique identifier of the array entry in my application.
AI Update

Great question! Yes, you can absolutely get both the resolved reference data and the _key field. The trick is to use GROQ's object projection syntax to explicitly select the fields you want.

Instead of just products[]->, you need to construct a new object that includes both the _key from the reference object and the dereferenced document:

products[] {
  _key,
  "item": @->
}

Or if you want to spread all the fields from the referenced document directly alongside _key:

products[] {
  _key,
  ...@->
}

The @ symbol refers to the current element in the array, and @-> dereferences it. The spread operator ... pulls all fields from the dereferenced document into your result object.

If you only need specific fields from the referenced document, you can be more selective:

products[] {
  _key,
  "productName": @->name,
  "productPrice": @->price,
  "productSlug": @->slug.current
}

This pattern is covered in the GROQ Query Cheat Sheet and there's also a helpful community answer thread about keeping the _key property when resolving references.

The key insight is that when you use products[]->, you're replacing each reference object with the dereferenced document, which is why you lose the _key. By using object projection with {}, you maintain control over exactly what fields end up in your result.

Can’t you use the _id of the product?
^ i use _id in this situation as well
Yes, I'm now using the _id as the key, but that is not ideal because technically the same product can appear in the array multiple times.
(i also have that issue from time to time 😂 )
This should work:
products[] {
  ...(@->),
  _key,
}

This works, thank you! :heart_hands:
Hi, I tried the above
user S
mentioned, but I still got
null
for the
_key
field, my GROQ looks like this, any idea?
Hi, I tried the above
user S
mentioned, but I still got
null
for the
_key
field, my GROQ looks originally like this, any idea?

_type=='peopleList' => {
    _key,
    _type,
    people[]->{
        _key,
        _type,
        name,
        position,
        bio,
        location,
        image {
            _key,
            _type,
            asset->{
                id,
                url,
                metadata,
                extension
            }
        },
    },
},
Is peopleList a document type? I think the _key field only exists on array entries. For documents you can use the _id as a unique id.
No, it is an object type, I can get the _key field there no problem actually. But I get null value for _key field in the people array which is a reference.
The
_key
is on the reference, not on the referenced document. So you need to merge.
Here's one way:
"people": people[] {
  _key,
  ...(@-> {
    _type,
    name,
    position,
    bio,
    location,
    // etc.
  })
}
For each ref, it merges in
@->
, which will resolve to the referenced document.
user S
Thanks you so much! This works!

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?