Querying for car brands with specific colors in Sanity.io

16 replies
Last updated: Dec 6, 2023
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.
Dec 6, 2023, 8:29 PM
user B
Sanity oficial Groq cheatset has an example on how to that, you could try something similar to:

&& "yellow" in color[].slug.current]

Dec 6, 2023, 8:34 PM
See more at the oficial docs here: https://www.sanity.io/docs/query-cheat-sheet
Dec 6, 2023, 8:35 PM
wow now that was fast, thank you I'll take a look
Dec 6, 2023, 8:35 PM
user T
thank you, the thing is, with this query I get zero results, so
[]


*[_type=="brand" && count(*[_type == "car" && references(^._id) && "yellow" in colors[].slug.current]) > 0]{
    title,
    "slug": slug.current
}
And with this I get at least one result, where I know the first color of an Audi is yellow:


*[_type=="brand" && count(*[_type == "car" && references(^._id) && colors[0]->slug.current == "yellow"]) > 0]{
     title,
    "slug": slug.current
}
If I combine them, just for a test, I still get, as expected my one Audi result:


*[_type=="brand" && count(*[_type == "car" && references(^._id) && colors[0]->slug.current == "yellow" || "yellow" in colors[].slug.current]) > 0]{
     title,
    "slug": slug.current
}
Can there something else be wrong? With the schema?
Dec 6, 2023, 8:44 PM
I think you can simplify your query. Brands are related to cars, so first get all the cards, then filter the cards by color, then return the distinct brands.
Dec 6, 2023, 8:53 PM
Color is a sub field of cars, not of an specific brand.
Dec 6, 2023, 8:56 PM
You are right I can sure flatten the query down and get all cars, and then their brands, but it's the same problem:

// work, it's basically the same as the querys above
*[_type=="car" && colors[0]->slug.current == "yellow"]

// does not work
*[_type=="car" && "yellow" in colors[].slug.current]
*[_type=="car" && "yellow" in colors[]->slug.current]
Dec 6, 2023, 8:58 PM
*[_type == "car" && count((colors[]->slug.current)[@ in ["yellow"]]) > 0)

Dec 6, 2023, 9:00 PM
*[_type=="car" && count((colors[]->slug.current)[@ in ["yellow"]]) > 0]
Trying to find an example for tyour use case, but something like this should work. You’d have to apply a
dinstinct
or unique filter to make sure brands woulnd’t be repeated
Dec 6, 2023, 9:01 PM
In situations like this,
<http://sanity.io|sanity.io>
cheatset is your best friend. https://www.sanity.io/docs/query-cheat-sheet
Dec 6, 2023, 9:02 PM
Lucas you got it right
Dec 6, 2023, 9:02 PM
Glad it worked 🙂
Dec 6, 2023, 9:02 PM
Have a look at the cheatset and you see special symbols in groq syntax like
@
that are quite useful when querying references 🙂
Dec 6, 2023, 9:03 PM
Wow
user T
it really works this way, thank you vey much, I'll take a look to understand why
Dec 6, 2023, 9:03 PM
It also works with the brands query now, combined with the cars, so the brands are unique there 🙂
Dec 6, 2023, 9:07 PM
Nice! Well done 🙂
Dec 6, 2023, 9:12 PM

Sanity– build remarkable experiences at scale

Sanity is a modern headless CMS that treats content as data to power your digital business. Free to get started, and pay-as-you-go on all plans.

Was this answer helpful?