
Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag storeI can help you with this GROQ query! The issue is that you can't use a nested *[...] filter inside a projection like that. Instead, you need to query from the top level and use the parent scope operator (^) to reference the outer query's document.
Here's the corrected query:
*[_type == 'publisher' && code == 'PUB1']{
"authors": *[_type == 'author' && references(^._id)]{
_id,
// include other author fields you need
}
}However, this uses the references() function which only works for direct references. Since your authors don't directly reference publishers (they reference books, which reference publishers), you need a different approach.
For your specific schema where the relationship is author -> books -> publisher, here's the working query:
*[_type == 'publisher' && code == 'PUB1']{
"authors": *[_type == 'author' && count(books[]->publisher._ref match ^._id) > 0]
}Or more efficiently using array filtering:
*[_type == 'publisher' && code == 'PUB1']{
_id,
"authors": *[_type == 'author' && ^._id in books[]->publisher._ref]
}How this works:
code == 'PUB1'^ operator references the current publisher document from the outer querybooks[]-> dereferences all book references in the author's books arraybooks[]->publisher._ref gets the publisher reference from each bookin operator checks if the current publisher's _id appears in that arrayThis will return your expected result where each publisher has an authors array containing all authors who have written at least one book for that publisher.
Alternative approach - If you need more control over the author data or want to include additional fields from the books, you could also query from the author perspective:
*[_type == 'author' && 'publisher1' in books[]->publisher._ref]{
_id,
name,
"relevantBooks": books[]->{
_id,
title,
publisher->
}[publisher.code == 'PUB1']
}The key insight is that GROQ's reference access operator (->) allows you to traverse relationships, and the parent scope operator (^) lets you reference values from outer queries when building nested projections.
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.
Content operations
Content backend


The only platform powering content operations
By Industry


Tecovas strengthens their customer connections
Build and Share

Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag store