Using conditional filters in GROQ queries in Sanity.io Slack channel
10 replies
Last updated: Feb 15, 2021
S
hey y'all! I'm wondering if it's possible to conditionally / optionally add a filter in a GROQ query. In this case, I want to add an operator if a certain reference exists on the document. My attempt looks like this, but doesn't appear to be working.
I basically want to say, if this post has a primaryCategory reference that has a slug, query that this slug equals the $primaryCategorySlug variable.
If the post doesn't have a primaryCategory reference, don't add the primaryCategory slug query.
*[ _type == "post" && slug.current == $slug && (defined(primaryCategory->slug.current) && primaryCategory->slug.current == $primaryCategorySlug ) ]
If the post doesn't have a primaryCategory reference, don't add the primaryCategory slug query.
Feb 14, 2021, 11:06 PM
P
Hi Sander, have you tried something like this?
FYI: inside projections you can achieve this more easily using so-called conditionals, in case you'd consider using nested queries -
https://www.sanity.io/docs/query-cheat-sheet#conditionals-64a36d80be73
*[ _type == "post" && slug.current == $slug && (!defined(primaryCategory->slug.current) || (defined(primaryCategory->slug.current) && primaryCategory->slug.current == $primaryCategorySlug) ) ]
https://www.sanity.io/docs/query-cheat-sheet#conditionals-64a36d80be73
Feb 15, 2021, 8:32 AM
S
Hey
user M
, I just tried using coalesce, which works:
*[ _type == "post" && slug.current == $slug && $primaryCategorySlug == coalesce(primaryCategory->slug.current, $primaryCategorySlug) ]
Feb 15, 2021, 8:46 AM
S
I think this works because if
primaryCategory->slug.currentdoesn't exist, it will compare
$primaryCategorySlugto itself, which would be true?
Feb 15, 2021, 8:46 AM
S
Your suggestion works as well. What would you consider the best approach?
Feb 15, 2021, 8:48 AM
P
Ah, definitely, I'd say
coalesce()is more elegant here, nice one 🙂
Feb 15, 2021, 8:59 AM
S
Cool, thank you! It looks a little cleaner for sure, with the drawback that you'd need to know how
coalesceoperates.
Feb 15, 2021, 9:07 AM
S
But I guess it's a pretty standard function in SQL land 🙂
Feb 15, 2021, 9:08 AM
R
I had to make it work both ways, as otherwise additional path parts could be added in to the URL:
*[ _type == "post" && slug.current == $slug && $primaryCategorySlug == coalesce(primaryCategory->slug.current, $primaryCategorySlug) && primaryCategory->slug.current == coalesce($primaryCategorySlug, primaryCategory->slug.current) ]
Feb 15, 2021, 9:34 AM
S
user M
For this in particular, Sanity would really benefit from having some sort of virtual field support that can consist of values of the document. In my case I would want to add a pathfield, that's built up from:
• predefined text string (e.g.
/blog)• reference slugs (and parent reference slugs) from categories (e.g.
/clothing&
/shirts• the document slug (e.g.
/basic-shirt)
Feb 15, 2021, 9:39 AM
S
Then if I have a URL
/blog/clothing/shirts/basic-shirt, I would be able to simply query documents that have this path, instead of making complicated queries like above.
Feb 15, 2021, 9:40 AM
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.