Help with GROQ join in Sanity.io for searching products by category.

15 replies
Last updated: Feb 15, 2021
Hello! I'm new here and am learning Sanity for a job I just got. I've been messing with the default ecommerce dummy data and am having a lot of trouble doing a GROQ join. Basically I am trying to search for a product with a category name, something like this but I am sure I am quite off base what I've tried so far. Thanks for any help 🙂
*[ _type == "product" ]{
  ...,
  "categories": *[ _type == "category" && ^._id in product[]._ref && slug.current == "swedish"],
}
AI Update

Welcome to Sanity! Great question - GROQ joins can be tricky at first, but once you get the hang of references, they're quite powerful.

The issue with your query is that you're trying to do the join "backwards." Instead of nesting another query inside, you want to dereference the category references and then filter the products based on those dereferenced values.

Here's the corrected approach:

*[_type == "product" && "swedish" in categories[]->slug.current] {
  ...,
  "categories": categories[]->{
    _id,
    title,
    slug
  }
}

Let me break down what's happening:

  1. categories[]->slug.current - The -> operator dereferences the array of category references, following them to get the actual category documents, then accesses their slug.current field

  2. "swedish" in categories[]->slug.current - This checks if "swedish" exists in the array of dereferenced category slugs (the in operator is perfect for array matching)

  3. "categories": categories[]->{...} - This expands the category references in your projection to include the full category data instead of just references

If you want to search by category name instead of slug, you can use:

*[_type == "product" && "Swedish" in categories[]->title]

Alternative using references(): If you already know the category's _id, you can use the references() function:

*[_type == "product" && references(*[_type == "category" && slug.current == "swedish"]._id)]

The Sanity GROQ recipe on filtering by category has great examples of this pattern. The key thing to remember is that the in keyword is used to find matches in an array, and the -> operator dereferences your array of category references so you can access their properties.

You can also check out the GROQ Query Cheat Sheet for more examples of working with references and arrays!

Welcome M M! When I’m trying more complex GROQ queries, I will usually try to simplify them to isolate the bit that isn’t working for me. In your example, I would try each of the three parts of the
categories
filter on its own to see what works and what doesn’t.
Are you comfortable using Vision for testing?
For example, when you run this do you get data back?

*[ _type == "product" ]{
  ...,
  "categories": *[ _type == "category"],
}

Hey Geoff! Yes I am using vision right now, have been at this for a bit haha. I am just a jr dev so I am comfortable with basic SQL joins but still relatively fresh haha
I get back all my products when I do that query!
so now I need to be able to search my categories table for the slug.current or title
Perfect. I’m wondering about that last bit—`slug.current == 'swedish'`—since the slug will normally be specific to one document.
Rather than typing it in GROQ, what are you hoping for your query to do?
well I am doing various search features for my product list
I have a category select drop down menu that displays dynamically from my getinitialprops in next and was hoping to filter by category
If you remove
&& slug.current == "swedish"
how close do you get to your desired result?
It doesn't, I believe it needs to reference category id somewhere and then search for the category title/slug
*[ _type == "category" && slug.current == "japanese"]{
  ...,
  "products": *[ _type == "product" && references(^._id) ]
}
I finally got it 🙂
thanks so much for helping me Geoff! Loving Sanity so far, it is really powerful
Excellent! Nice work! 🙌
Yes, it sure is! Enjoy your time with it!
🙂

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?