Is it possible to match values in arrays using a groq query in Sanity.io?

2 replies
Last updated: Oct 18, 2023
Is it possible to match any value in an array with another array in a groq query? πŸ€”
Something like this:
*[_type == "event" && ^.filter.tags[]._ref in tags[]._ref && eventStart > now()]
?
AI Update

Yes, it's absolutely possible to match any value in an array with another array in a GROQ query! The key is using the in operator correctly.

Your example query is close, but the syntax needs adjustment. Here's how to do it:

Using the in operator

The in operator checks if the left-hand operand is contained within the right-hand operand (which can be an array). When the right-hand operand is an array, GROQ compares the left-hand operand for equality with each element, returning true when a match is found.

For your use case, you want to check if any tag reference in your document matches any tag reference in the filter:

*[_type == "event" && count(tags[]._ref[@ in ^.filter.tags[]._ref]) > 0 && eventStart > now()]

This works by:

  1. Using tags[]._ref to get all tag references from the event
  2. Filtering those with [@ in ^.filter.tags[]._ref] to find matches
  3. Using count() to see if any matches exist

Alternative approach

If you're working with reference fields, you might also consider using the references() function if you're checking against specific document IDs:

*[_type == "event" && count(tags[]._ref[@ in ^.filter.tags[]._ref]) > 0 && eventStart > now()]

Simpler pattern for direct array comparison

The pattern you mentioned in your question is actually quite close! The key insight is that in compares a single value against an array, so you need to iterate through your first array and check each element against the second array:

// Check if any tag from the document is in the filter tags
*[_type == "event" && count(tags[]._ref[@ in ^.filter.tags[]._ref]) > 0]

The count() function then tells you if any matches were found. If the count is greater than 0, at least one tag matched!

This is the recommended approach in GROQ for checking array intersections, as mentioned in the GROQ operators documentation.

Asked ChatGPT and it hallucinated a
some
keyword. πŸ˜›
Figured it out.

*[_type == "event" && count((tags[]._ref)[@ in  ^.filter.tags[]._ref]) > 0 && eventStart > now()]

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?