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

Adjusting GROQ query to filter out current document based on tags.

2 replies
Last updated: Jun 12, 2023
Still learning how to write more advanced custom GROQ queries and I'm using this to return all related documents based on tags:
"related": *[_type == "post" && count(categories[@._ref in ^.^.categories[]._ref]) > 0] | order(publishedAt desc, _createdAt desc) [0..5] {
     title,
     slug
   }
(as found here:
https://www.sanity.io/schemas/get-related-items-of-a-post-in-sanity-by-comparing-category-array-reference-with-another-array-0d752dd7 )
However, this returns the current document again, as it's got the same tags. How can I adjust this to filter out the current document? (something like
slug.current != slug
but this doesn't take into consideration what the ^ and @ operators do (still learning this).
Jun 11, 2023, 4:43 PM
The caret (
^
) is the parent operator, which means it goes one level up in scope. A filter boils down to one or more booleans, returning every document that matches them all. By adding an additional check to your “related” filter that ensures the document doesn’t match the parent, you can avoid returning the current document again. Something like
_id != ^._id
should work.

"related": *[_type == "post" && count(categories[@._ref in ^.^.categories[]._ref]) > 0 && _id != ^._id] // ...
Here,
_id
is in the context of the “related” filter, while
^._id
is in the context of the parent (not shown in the original post, but implied to exist).
Jun 11, 2023, 6:49 PM
This is perfect. Brilliant explanation. I've used the
^
operator once, but not fully grasped it. This is great. Thanks!
Jun 12, 2023, 1:20 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?