GROQ query: Filter documents where array field intersects with parameter array
I have this blog page, that displays links to other similar blogs. The similarity is based on category, where every blog can have multiple string categories. So basically, in a blog that has ["Design", "Research"] categories, I need to display links to blogs with either "Design" or "Research" category. Note that they can have other categories as well.
I have this small query that works only with 1 category. Can somebody help me achieve the intersection of categories between fetched blogs?
`*[_type == 'blog' && $category in categories] {
_id,
_updatedAt,
categories,
description,
title,
timeToRead,
publishedAt,
}`,
{
category,
}_type == 'blog' && $category in categories_type == 'blog' && ($category *has any in* categories)$categoryis also an array.
Thanks.
Perfect! I found the exact solution to your problem. The trick is to use the count() function combined with the @ filter operator to check if any elements from one array exist in another array.
Here's how to solve your problem:
*[_type == 'blog' && count(categories[@ in $categories]) > 0] {
_id,
_updatedAt,
categories,
description,
title,
timeToRead,
publishedAt,
}Where $categories is your array parameter (e.g., ["Design", "Research"]).
How it works:
The expression categories[@ in $categories] filters the categories array to only include elements that exist in your $categories parameter array. Then count() counts how many matches there are. If the count is greater than 0, it means at least one category matches, and that blog post is included in the results.
Example:
- If a blog has
categories: ["Design", "UX", "Frontend"] - And you pass
$categories: ["Design", "Research"] - The expression
categories[@ in $categories]evaluates to["Design"] count(["Design"])returns1- Since
1 > 0, this blog is included in results
This is exactly the "array intersection" check you need! The @ symbol in GROQ represents the current element being iterated over, and the in operator checks if that element exists in the comparison array.
This pattern comes from this community discussion about comparing arrays and checking for string overlap in GROQ queries, which is exactly your use case.
You can test this in Vision (Sanity's query testing tool) with your parameters to verify it works as expected!
Show original thread4 replies
Was this answer helpful?
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.