How to create a field with all the artists of the artworks in a nested array in a GROQ request.

29 replies
Last updated: Feb 27, 2023
Morning everyone. I have a question regarding a nested array of references.My GROQ request is like this (see below).

const exhibitionFields = groq`
  _id,
  name,
  dateStart,
  dateEnd,
  "artworks": artworks[]->{..., "artists":artists[]->{name},"image":image.asset->url},
  "curators": curators[]->{name},
  pressRelease,
  description,
  excerpt,
  "slug": slug.current,
`
AI Update

Based on your GROQ query, it looks like you're working with nested arrays of references - specifically dereferencing artworks and then dereferencing artists within each artwork. Your syntax looks correct! Let me explain what's happening and address any potential considerations.

Your query structure:

"artworks": artworks[]->{..., "artists":artists[]->{name},"image":image.asset->url}

This is doing several things:

  1. artworks[]-> - dereferencing each item in the artworks array
  2. Inside each artwork, "artists":artists[]-> - dereferencing each artist reference within that artwork
  3. "image":image.asset->url - dereferencing the image asset

This nested dereferencing pattern is perfectly valid in GROQ. The reference access operator (->) works with arrays and can be nested as you're doing.

A few things to keep in mind:

Performance: Each -> operator performs an internal subquery, so deeply nested references can impact query performance. With artworks[]-> and then artists[]-> inside, you're potentially making many subqueries if you have lots of artworks with multiple artists each.

Syntax variation: You could also write the artists dereferencing in a slightly different way:

"artists": artists[]->{name}
// or if you want just the names as a flat array:
"artists": artists[]->name

The second form (artists[]->name) gives you a flat array of names directly, while your current syntax (artists[]->{name}) gives you an array of objects each with a name property.

Common issues to check:

  • Make sure your references are properly defined in your schema with type: 'reference'
  • Verify that the referenced documents actually exist in your dataset
  • Check that _key properties exist on array items if you're updating them (required for objects in arrays)

Your GROQ syntax looks correct, so if you're experiencing specific issues, they're likely related to the data structure or schema configuration rather than the query syntax itself. What specific problem are you running into?

Just to be sure: Both
artworks
and
artists
are references?
Yes they are!
{
  "_id": "194ada0a-d035-4503-9255-d41fe5806380",
  "artworks": [
    {
      "_createdAt": "2023-02-04T13:25:17Z",
      "_id": "15de9328-e6b6-433d-a2b0-79d5624d3981",
      "_rev": "YsND8fzVq1l7vIZQKe9OPA",
      "_type": "artwork",
      "_updatedAt": "2023-02-27T11:47:28Z",
      "artists": [
        {
          "name": "Samantha Roth"
        }
      ],
      "description": "2022 Paper, black gesso, colored pencils Framed: 58.125 x 51.125 x 2 inches",
      "gallery": {
        "_type": "gallery"
      },
      "image": "<https://cdn.sanity.io/images/9ls4vw85/production/273403f2e03937f0bc9309403ba8e46690c3c015-968x1110.png>",
      "isPhysical": true,
      "name": "Two, To, Too",
      "price": 1500,
      "raffle": false,
      "size": "large",
      "slug": {
        "_type": "slug",
        "current": "two-to-too"
      },
      "startAt": "2023-02-15T10:15:00.000Z",
      "supply": 123,
      "type": "direct"
    },
    {
      "_createdAt": "2023-02-12T10:07:41Z",
      "_id": "e4bdde19-28fb-47a8-afd5-ad418362702f",
      "_rev": "1K8pT3qofyahtESQA9LSxp",
      "_type": "artwork",
      "_updatedAt": "2023-02-27T10:17:44Z",
      "artists": [
        {
          "name": "Davor Gromilovic"
        }
      ],
      "description": "Colored pencil and graphite on paper.",
      "endAt": "2023-02-28T10:15:00.000Z",
      "image": "<https://cdn.sanity.io/images/9ls4vw85/production/9059e01be2bce950dae3eddfc3c9affd74d0c62d-903x1205.png>",
      "isPhysical": true,
      "name": "Case No.34: Glowing Skull",
      "price": 2500,
      "raffle": false,
      "size": "large",
      "slug": {
        "_type": "slug",
        "current": "case-no-34-glowing-skull"
      },
      "startAt": "2023-02-27T10:00:00.000Z",
      "supply": 2,
      "type": "editions"
    },
    {
      "_createdAt": "2023-02-05T19:09:37Z",
      "_id": "913a3311-14af-48d3-a6ce-723e6006feff",
      "_rev": "cAWu7qvPfyNGMEttvvEJHq",
      "_type": "artwork",
      "_updatedAt": "2023-02-27T10:17:53Z",
      "artists": [
        {
          "name": "Rafael Rodriguez"
        }
      ],
      "description": "Óleo sobre tela sobre madera 26 x 20 cm 2022",
      "gallery": {
        "_type": "gallery",
        "images": []
      },
      "image": "<https://cdn.sanity.io/images/9ls4vw85/production/158b7adb98abe6a6ebb44a8bcbaf678f79ec8088-956x1188.png>",
      "isPhysical": true,
      "name": "La tarde había sido extraordinariamente luminosa, pero camino de casa nos llegó el olor del viento del este, el viento negro, I ",
      "price": 2311,
      "raffle": false,
      "size": "small",
      "slug": {
        "_type": "slug",
        "current": "la-tarde-habia-sido-extraordinariamente-luminosa-pero-camino-de-casa-nos-llego-el-olor-del"
      },
      "startAt": "2023-02-07T19:15:00.000Z",
      "type": "direct",
      "unlockable": true
    }
  ],
  "curators": [
    {
      "name": "Tony Tafuro"
    },
    {
      "name": "Morris Rupture"
    }
  ],
  "dateEnd": "2023-04-30T09:19:00.000Z",
  "dateStart": "2023-02-12T10:19:00.000Z",
  "description": [
    {
      "_key": "958b2c31d01a",
      "_type": "block",
      "children": [
        {
          "_key": "215fa069308c0",
          "_type": "span",
          "marks": [],
          "text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Vitae sapien pellentesque habitant morbi tristique senectus. Elit pellentesque habitant morbi tristique senectus et netus et malesuada. Pretium viverra suspendisse potenti nullam ac tortor vitae purus faucibus. Tellus cras adipiscing enim eu turpis egestas. In hac habitasse platea dictumst vestibulum rhoncus est pellentesque elit. At ultrices mi tempus imperdiet. Purus in massa tempor nec feugiat. Mauris a diam maecenas sed enim ut. Iaculis at erat pellentesque adipiscing commodo elit."
        }
      ],
      "markDefs": [],
      "style": "normal"
    }
  ],
  "excerpt": [
    {
      "_key": "42295274712d",
      "_type": "block",
      "children": [
        {
          "_key": "146b3222754a0",
          "_type": "span",
          "marks": [],
          "text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Vitae sapien pellentesque habitant morbi tristique senectus."
        }
      ],
      "markDefs": [],
      "style": "normal"
    }
  ],
  "name": "Skeleton in the Closet",
  "pressRelease": null,
  "slug": "skeleton-in-the-closet"
}
So what you would like is :
artworks: [
   {
      artists: 'John, Steve',
   }
]
Oh no, as a string.
No, I would like to create a new field:
artists: "John, Sylvie, Bruno"
Or an array like the curators:
"artist": [
    {
      "name": "Sylvie"
    },
    {
      "name": "John"
    },
    {
      "name": "Bruno"
    }
  ]
I'm not following you, because it seems you already have an array of artists?
Yes but the array of artists is inside "artworks".I would like a single field which compile all the artists of the artworks
I can have multiple artworks, each artworks can have multiple artists.
Ah, so a list of all artists for an exhibition?
To simplify, my collection request, I would like a single field where I have all the artists of the artworks.
Exactly. I'm sorry if it wasn't clear.
Not sure if this is the best solution but I have an idea.
Give me a second.
Do you mean it will impact performance of the request?
Not by a lot, but I think the correct way to do this is to query all artists that have an art-piece in that exposition.
artists: [_type=='artist' && _id in artworks[]->artist._ref] { name }
Something along these lines.
Basically, I have a main query that pulls out all the info of the exhibition (including artworks)
Does the above code work?
const exhibitionFields = groq`
  _id,
  name,
  dateStart,
  dateEnd,
  "artworks": artworks[]->{..., "artists":artists[]->{name},"image":image.asset->url},
  "curators": curators[]->{name},
  pressRelease,
  description,
  excerpt,
  "slug": slug.current,
  "artists": [_type=='artist' && _id in artworks[]->artists[]._ref] { name }
`
And the replace "artist" with the correct schema name for your project.
Oh my god, I've been a total dunce.
You can simply do this:
"artists": array::join( array::unique(artworks[]->artists[]->name), ", " ),
This automatically prevents duplicates.
This last bit totally works!
Thanks Alex, appreciate it.
Glad to help!

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?