👋 Next.js Conf 2024: Come build, party, run, and connect with us! See all events

Filtering by array references in Sanity.io

20 replies
Last updated: Apr 7, 2022
Is there a way to filter by elements of an array of references? I have a ProductListing type which references many Products. I want to get all listings that have at least one product in stock. I can’t seem to be able to figure this one out.
I tried a few options along these lines, but it doesn’t seem to work:

*[_type=='ProductListing' && items[]->stock > 0]{
  _id
}
I was looking for something like a
sum
function or any way to filter items without doing a select and filtering client side.I will have more conditions as well based on whether items are currently disabled and such.
Apr 6, 2022, 5:55 PM
What does this return?

*[_type=='ProductListing']{
  'items': items[]->stock
}
Apr 6, 2022, 6:06 PM
Yes, it’s an array of references
Apr 6, 2022, 6:06 PM
[
  {
    "items": [
      10000000,
      0,
      999998,
      0,
      11
    ]
  }
]
Apr 6, 2022, 6:07 PM
Thanks for confirming. Could you try this?

*[_type=='ProductListing' && count(items[]->stock) > 0]
Apr 6, 2022, 6:07 PM
Thanks for confirming. Could you try this?

*[_type=='ProductListing' && count(items[]->stock) > 0]
Apr 6, 2022, 6:08 PM
*[_type=='ProductListing' && count(items[]->stock) > 0]{
  'items': items[]->stock,
}[0..1]
Apr 6, 2022, 6:08 PM
[ {
“items”: [
10000000,
0,
999998,
0,
11
]
},
{
“items”: [
999
]
}
]
Apr 6, 2022, 6:08 PM
Hm, it could actually be working
Apr 6, 2022, 6:08 PM
let me look through a larger set
Apr 6, 2022, 6:08 PM
{ “items”: [
0
]
}
Apr 6, 2022, 6:09 PM
Found this
Apr 6, 2022, 6:09 PM
I will let it sit till the morning. Let me know if you have ideas on filtering through references on one or more conditions. Perhaps a
score
could work somehow
Apr 6, 2022, 6:11 PM
Yeah, that was bad advice on my part, sorry. I think you may want a join. Just going to test something locally to get the code right.
Apr 6, 2022, 6:11 PM
Something like:

*[_type=='ProductListing']{
  'items': items[]->stock,
}[items[]->stock != 0]

Apr 6, 2022, 6:12 PM
{ “items”: [
0
]
}
Apr 6, 2022, 6:12 PM
Still a few
Apr 6, 2022, 6:12 PM
Is there a way to intersect two arrays? let’s say I would do something like:

items[]._ref in *[filter]._id
Apr 6, 2022, 6:16 PM
Okay, apologies again! I think this may finally capture it:

*[_type == 'ProductListing']{
  'items': items[(@->stock != 0)]->stock,
  _id
}[length(items) > 0]
This requires
v2021-03-25
or later of the API.
Apr 6, 2022, 6:32 PM
Wow. Works like magic. I was able to expand on the filter further with additional conditions! Long live GROQ
Apr 7, 2022, 6:58 AM
Awesome! Glad you got this working! 🙌
Apr 7, 2022, 5:09 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?