GROQ query not filtering posts by category reference correctly
I can see the issue with your query! The problem is in your filter condition within the subquery. You're comparing category._id (from the post) with ^.categories._ref, but the correct path should be ^._id to reference the parent category's ID.
Here's the corrected query:
*[_type == "category"]{
_id,
title,
"post": *[_type == "post" && references(^._id)]
}The references() function is actually the cleanest way to handle this. It will find all posts that have a reference to the current category's ID.
Alternatively, if you want to be more explicit about the field path, you can use:
*[_type == "category"]{
_id,
title,
"post": *[_type == "post" && category._ref == ^._id]
}The key issues with your original query were:
- You used
category._idinstead ofcategory._ref- references store the ID in a_refproperty - You used
^.categories._refwhich doesn't exist on the category document - you just need^._idto access the parent category's ID
The ^ operator allows you to access the parent scope within the subquery, so ^._id refers to the category's _id that you're currently iterating over in the outer query.
If you want to return additional fields from the posts, you can expand the projection:
*[_type == "category"]{
_id,
title,
"posts": *[_type == "post" && references(^._id)]{
title,
slug,
publishedAt
}
}Show original thread6 replies
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.