Unlock seamless workflows and faster delivery with our latest releases – get the details

Comparing arrays and checking for string overlap in GROQ queries.

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
May 26, 2021, 1:47 AM
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.
May 26, 2021, 12:22 PM
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.
May 26, 2021, 12:31 PM
Apparently you can’t query for arrays unless you implement some sort of workaround as mentioned in this thread .
May 26, 2021, 3:16 PM
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.
May 26, 2021, 7:13 PM
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.
May 26, 2021, 7:26 PM
The
count
+
@
trick from the thread quoted above looks useful. 👍
May 26, 2021, 7:43 PM
[count(['hello', 'world'][@ in ['hello', 'sanity']]) > 0]
May 26, 2021, 7:59 PM
It took me a while, but I’m following what you mean now. Thanks for helping me get there. 🙌
May 26, 2021, 8:02 PM
That is indeed a handy trick from Peter, and well-adapted above to Jonathan’s question.
May 26, 2021, 8:04 PM
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!
May 26, 2021, 10:18 PM

Sanity– build remarkable experiences at scale

Sanity is a modern headless CMS that treats content as data to power your digital business. Free to get started, and pay-as-you-go on all plans.

Was this answer helpful?