Compare two string arrays for common elements in GROQ

10 replies
Last updated: May 26, 2021
Hi everyone, is it possible to compare two arrays (of strings) and check if any strings are in both arrays with GROQ?for example...

['hello', 'world']
and
['sanity', 'cms']
would return false
['*hello*', 'world']
and
['*hello*', 'sanity']
would return true as
'hello'
is in both arrays
AI Update

Yes, absolutely! You can check if two arrays have any overlapping strings using the in operator combined with count() in GROQ. Here's how:

count(['hello', 'world'] @ in ['hello', 'sanity']) > 0

This would return true because 'hello' appears in both arrays.

How it works

The @ symbol in GROQ represents "each element" in the array. The expression array1 @ in array2 iterates through each element of array1 and checks if it exists in array2, returning an array of matching elements. Then count() tells you how many matches were found.

Breaking it down:

  • ['hello', 'world'] @ - iterates through each element ('hello', then 'world')
  • @ in ['hello', 'sanity'] - checks if the current element exists in the second array
  • count(...) - counts how many elements matched
  • > 0 - returns true if there's at least one match

Practical example with documents

This is especially useful when filtering documents. For example, if you have posts with tags and want to find posts that have any tags matching a specific list:

*[_type == 'post' && count(tags[] @ in $selectedTags) > 0]

Or checking if two reference arrays have any overlap:

*[_type == 'article' && count(authors[]._ref @ in $authorIds) > 0]

Checking for complete intersection

If you want to check that all elements from one array exist in another (not just any), you can compare the count to the array length:

count(['hello', 'world'] @ in ['hello', 'world', 'sanity']) == 2

The count() function works perfectly with the in operator for these kinds of array intersection checks. This pattern of count(array1 @ in array2) > 0 is a common and efficient way to check for array overlap in GROQ queries, and it's particularly powerful when used in filter components to narrow down your document results based on array intersections.

Show original thread
10 replies
That seems to assume there is one particular string to check. I believe the question is about checking if any arbitrary string is in both arrays, i.e. if the arrays overlap (as in the
&&
array operator in PostgreSQL, for instance). I have the same problem.
In fact I've encountered an even harder problem—doing the same kind of overlap check but comparing case-insensitively. Unless I'm missing something, GROQ seems mostly targeted towards working with simple fields on the document level and has few tools to work with arrays. (Or objects?) I didn't find any
unnest
-like functionality either (which is a thing in e.g. PostgreSQL and BigQuery's SQL dialects, to expand into a set of rows that can then be `SELECT`ed from), to "promote" array entries into things that can be filtered/etc.
Apparently you can’t query for arrays unless you implement some sort of workaround as mentioned in this thread .
As Øyvind mentioned, if you want to query for a variable string, you can pass it in via params and plug that into your query:
In Vision:


// Params

{
  "string": "hello"
}

// Query

[$string in ['hello', 'world'] && $string in ['sanity', 'cms']] // Returns false
[$string in ['hello', 'world'] && $string in ['hello', 'sanity']] // Returns true
If you were using the
JS client ,
client.fetch()
has a second parameter that takes an object of params.
But imagine that one of the two arrays comes from the params. E.g. you're trying to search in Sanity documents that can have an arbitrary amount of keywords, and the user can input an arbitrary amount of keywords that they want to search for (appearing in params as an array), and get a result list that includes all documents that match at least one keyword.
The
count
+
@
trick from the thread quoted above looks useful. 👍
[count(['hello', 'world'][@ in ['hello', 'sanity']]) > 0]
It took me a while, but I’m following what you mean now. Thanks for helping me get there. 🙌
That is indeed a handy trick from Peter, and well-adapted above to Jonathan’s question.
Thanks for providing more clarity around my question Øyvind. I did see the
count
+
@
expression in the docs and wondered if that might've been the answer but couldn't figure it out. But it works perfectly. Also thanks Racheal and Geoff!

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?