GROQ: Query brands with cars having specific color in array of references

16 replies
Last updated: Nov 29, 2025
Hey,
I've a GROQ question. Let's say I have following data and schemas:

• Brands (Car Brands like Audi, Volvo, VW, etc.)
• Cars (Cars like Audi A4, Audi A4, Volvo XC40, VW Golf, etc.)
• Colors (Black, White, Red, Green, etc.)
The Car schema has a reference to
one
brand
and a reference to multiple
colors
(as an array per schema definition), since every car is available in different and multiple colors.

// car.tsx

const carSchema = defineType({
  name: 'car',
  type: 'document',
  title: 'Car',
  //...
  fields: [
    //..
    defineField({
      name: 'brand',
      title: 'Brand',
      type: 'reference',
      readOnly: true,
      to: [{ type: 'brand' }],
    }),
    //..
    defineField({
      name: 'colors',
      title: 'Colors',
      type: 'array',
      of: [
        defineArrayMember({
          type: 'reference',
          to: [{ type: 'colors' }],
        }),
      ],
    }),
    //..
  ],
  preview: {
    //...
  },
})

export default carSchema
Now I want to query for all car brands that have let's say
yellow
cars available, my problem is, that I'm unsure how I can make a condition on a referenced slug.
This GROQ query I made is partially working, but of course it only checks the first color (
color[0]
) for yellow, so I only get brands where the first set color of a car was yellow.
Any way to check all referenced color slugs?


*[_type=="brand" && count(*[_type == "car" && references(^._id) && color[0]->slug.current == "yellow"]) > 0]{
    title,
    "slug": slug.current
}
Current result, but of course there are many missing:

[ { "title": "Audi", "slug": "audi" } ]
Thank you very much.
AI Update

The issue with your query is that you're only checking the first element of the colors array with color[0]->slug.current == "yellow". To check if any color in the array matches "yellow", you need to use array filtering techniques in GROQ.

Here's the corrected query:

*[_type=="brand" && count(*[_type == "car" && references(^._id) && "yellow" in colors[]->slug.current]) > 0]{
    title,
    "slug": slug.current
}

The key change is "yellow" in colors[]->slug.current. Here's what's happening:

  • colors[] - This expands the array of color references
  • ->slug.current - This dereferences each color and gets its slug
  • "yellow" in colors[]->slug.current - This checks if "yellow" exists anywhere in the resulting array of slugs

Alternative approach using array filtering:

You can also use array filtering with the @ operator for more explicit filtering:

*[_type=="brand" && count(*[_type == "car" && references(^._id) && count(colors[@->slug.current == "yellow"]) > 0]) > 0]{
    title,
    "slug": slug.current
}

This works by:

  • colors[@->slug.current == "yellow"] - Filters the colors array to only include references where the slug is "yellow"
  • count(...) > 0 - Checks if at least one color matched

Both approaches will find all brands that have at least one car available in yellow, regardless of where yellow appears in the colors array.

The first approach ("yellow" in colors[]->slug.current) is generally more concise and readable for simple equality checks like yours. This should give you all the brands (Audi, Volvo, VW, etc.) that have at least one car model available in yellow!

Show original thread
16 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?