Filter array of strings in Sanity query returning null

23 replies
Last updated: May 30, 2023
Anyone able to help me here? I'm trying to filter an array (
platform
) of strings. Tried several ways but they keep returning null
example of what platform would look like ['ios', 'android']


*[_type == 'bannerQueue'] {
  banners[]->{
    _id,
    bannerType,
    "description": description[$lang],
    "imageUrl": image.asset->url,
    platform,
  }
}[0]
AI Update

I can help you with filtering an array of strings in GROQ! Based on your example where platform is an array like ['ios', 'android'], here are the correct ways to filter it:

If you want to filter documents where platform contains a specific value:

*[_type == 'bannerQueue' && "ios" in platform] {
  banners[]->{
    _id,
    bannerType,
    "description": description[$lang],
    "imageUrl": image.asset->url,
    platform,
  }
}[0]

The in operator checks if a value exists in an array. So "ios" in platform returns true if the platform array contains "ios".

If you want to filter banners based on their platform array:

*[_type == 'bannerQueue'] {
  banners[]->{
    _id,
    bannerType,
    "description": description[$lang],
    "imageUrl": image.asset->url,
    platform,
  }["ios" in platform || "android" in platform]
}[0]

Here you're dereferencing the banners first with []->, then filtering the results with another filter that checks if the platform array contains your desired values.

Common reasons for getting null:

  1. Missing the in operator - You need "ios" in platform, not platform == "ios"
  2. Filter placement - Make sure your filter comes after the dereference operator (->) if you're filtering the referenced documents
  3. Array syntax - Remember to use []-> when dereferencing an array of references

The key insight from the GROQ documentation is that the in operator is specifically designed for matching values in arrays: *["sci-fi" in genres] matches all documents where genres is an array containing the value "sci-fi".

Try the first example if you're filtering at the bannerQueue level, or the second if you need to filter the individual banners after dereferencing them!

Show original thread
23 replies
Are you getting
null
or an array of `null`s?
just null
*[_type == 'bannerQueue' && "android" in banners[]->platform] {
  banners[]->{
    _id,
    bannerType,
    "description": description[$lang],
    "imageUrl": image.asset->url,
    platform,
  }
}[0]
One of the things I've tried
Is
bannerQueue
(case-sensitive) a valid document type?
yes it is
Oh, is that second one your actual query?
The first sample code I provided return correct results unfiltered
If
platform
is an array, can you please try:

*[_type == 'bannerQueue' && "android" in banners[]->platform[]]
That just returns all the results again unfiltered
It’s not limiting the documents to just those with “android” in the
platform
array?
nope!
Index 1 doesn't contain android
this kind of nesting always confuses me. I do something similar but don’t quite remember if this is the solution…

*[_type == 'bannerQueue' && count((banners[]->platform)["android" in @]) > 0]
It looks like your
bannerQueue
document contains an array with two banners. Your current filter is being met, since at least one of those banners contains ‘android’. You need to move the filter down to the banners array itself.
I've tried a few ways in the banner array itself as well. Is there an issue with my syntax?

*[_type == 'bannerQueue'] {
  banners["android" in platform[]]->{
    _id,
    bannerType,
    "description": description[$lang],
    "imageUrl": image.asset->url,
    platform,
  }
}[0]
Ah. I see. The filter we’ve been adjusting is for the document(s) returned, which in your case, it’s doing (and just the one document). You’ll want to filter the items returned by the
banners
array. I think you’ll need something like this to limit your
banners
array:

*[_type == 'bannerQueue' && "android" in banners[]->platform[]] {
  banners["android" in @->banners[].platform[]]->{
    _id,
    bannerType,
    "description": description[$lang],
    "imageUrl": image.asset->url,
    platform,
  }
}[0]
This feels like it won’t be very performant, and it’s not tested, but I’ll try to loop back to it later.
user M
Yep that makes sense!
Ideally the
"android" in…
stuff would come after the dereference and allow that instance of the dereference to be removed, but not sure if that’s possible.
Unfortunately still getting no results 😢
Sorry. This:

banners["android" in @->banners[].platform[]]->{
Should be this:


banners["android" in @->platform[]]->{
That works!
Great! Thanks for confirming. I’ll still see if there might be a more performant approach, but I’m glad to hear you’re able to filter the data correctly. 🙌
Appreciate the help!! 🙌

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?