Using conditional filters in GROQ queries in Sanity.io Slack channel

10 replies
Last updated: Feb 15, 2021
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.

*[
  _type == "post" &&
  slug.current == $slug &&
  (defined(primaryCategory->slug.current) &&
    primaryCategory->slug.current == $primaryCategorySlug
  )
]
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.
Feb 14, 2021, 11:06 PM
Hi Sander, have you tried something like this?
*[
  _type == "post" &&
  slug.current == $slug &&
  (!defined(primaryCategory->slug.current) || 
    (defined(primaryCategory->slug.current) &&
    primaryCategory->slug.current == $primaryCategorySlug)
  )
]
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
Feb 15, 2021, 8:32 AM
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
I think this works because if
primaryCategory->slug.current
doesn't exist, it will compare
$primaryCategorySlug
to itself, which would be true?
Feb 15, 2021, 8:46 AM
Your suggestion works as well. What would you consider the best approach?
Feb 15, 2021, 8:48 AM
Ah, definitely, I'd say
coalesce()
is more elegant here, nice one 🙂
Feb 15, 2021, 8:59 AM
Cool, thank you! It looks a little cleaner for sure, with the drawback that you'd need to know how
coalesce
operates.
Feb 15, 2021, 9:07 AM
But I guess it's a pretty standard function in SQL land 🙂
Feb 15, 2021, 9:08 AM
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
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
path
field, 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
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.

Was this answer helpful?