GROQ: Filter posts by category when categories is an array field
When filtering posts by a category field that's an array of references in GROQ, you have several options depending on what you're trying to achieve:
Basic Array Filtering
To check if a specific category reference exists in the array:
*[_type == "post" && "category-id-here" in categories[]._ref]This checks if the category ID appears in the _ref field of any item in the categories array.
Filter by Category Slug
If you want to filter by a category's slug (after dereferencing):
*[_type == "post" && "my-category-slug" in categories[]->slug.current]The -> operator dereferences each category reference and lets you access its properties.
Filter by Multiple Categories (OR)
To find posts that have any of several categories:
*[_type == "post" && count((categories[]._ref)[@ in ["cat-id-1", "cat-id-2"]]) > 0]Or with slugs:
*[_type == "post" && count((categories[]->slug.current)[@ in ["action", "thriller"]]) > 0]Filter by Multiple Categories (AND)
To find posts that have all of the specified categories:
*[_type == "post" && count((categories[]->slug.current)[@ in ["action", "thriller"]]) == 2]Just adjust the == 2 to match the number of categories you're requiring.
Using the references() Function
For a cleaner syntax when checking a single category:
*[_type == "post" && references("category-id-here")]This checks if the document references the specified ID anywhere in its reference fields.
The key thing to remember is that categories[]._ref gives you an array of the referenced IDs, and you can use the in operator or count() function to check membership. The -> operator is super handy for accessing properties of the referenced documents directly in your query.
Show original thread6 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.