GROQ: Resolve array references while keeping _key property

8 replies
Last updated: Mar 1, 2021
Hi guys, I have a simple array of references within a document. Does anyone know the GROQ query I need to write to resolve references AND keep the _key property for each element in the array?

This query: *[_id == $id]{items}

Gives me this result:
[
  {
    "items": [
      {
        "_key": "1acc50cf5ffc",
        "_ref": "f4cae0ea-16a0-446b-a835-a93b001dd1eb",
        "_type": "reference"
      },
      {
        "_key": "be9bad61ab5e",
        "_ref": "098b7fce-f26c-4643-90c1-8ef6b8f61bbf",
        "_type": "reference"
      }
    ]
  }
]
Adding
[]->
to items resolves each item reference, but it also strips out the
_key
property. Is there a way to include it while still resolving the reference all with a single GROQ query?
AI Update

Perfect! I found exactly what you need. When you use the -> operator to dereference, it strips out the _key property, but there's a clean way to preserve it.

You can explicitly include the _key in your projection while spreading the dereferenced content:

*[_id == $id]{
  items[]{
    _key,
    ...(@->)
  }
}

This pattern works by:

  1. items[] - iterates over each item in the array
  2. _key - explicitly includes the key property
  3. ...(@->) - spreads all properties from the dereferenced document (the @ refers to the current item being iterated)

So if your referenced documents have properties like title and description, your result would look like:

[
  {
    "items": [
      {
        "_key": "1acc50cf5ffc",
        "title": "First Item",
        "description": "..."
      },
      {
        "_key": "be9bad61ab5e",
        "title": "Second Item",
        "description": "..."
      }
    ]
  }
]

This is the recommended approach for preserving _key during dereferencing, and it's especially useful when you need those keys as React key props when rendering lists!

Show original thread
8 replies
Out of interest... why do you need to keep the
_key
property? Just curious
I need to create relative references to the documents inside this document. I have a separate array of objects where each object has a relative reference to an item in the array. At the same time I also need to resolve the item in order to determine it's type. The
items
array can contain references to many different types and I'm using a custom InputComponent to filter out references based on the values in other fields.
Hi User. One way would be to call for the dereferenced data as well as the key. Something like:

*[_id == $id]{
  'items': items[]->,
  'itemKey': items[]._key
}

Or you could do this:
*[_id == $id]{
  items[]{
    ...,
    "doc": *[_id == ^._ref][0]
  }
}
So you're adding a new property,
doc
to each of the items in the
items
array which fetches the referenced document
Nice. Thanks for the answers
user A
and
user M
. Both solutions seem to work fine. Though I think I prefer
user M
s solution as it groups the document with the item. Thank you both!
Another variation, which is slightly faster:

*[_id == $id]{
  items[]{
    _key,
    ...(@->)
  }
}
"Take _key from the array item, then splat all the properties of following this reference"
Oh, that is lovely
user Z
🤩

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?