Querying for subcategories of articles written by a specific author in a nice way.
Looking at your GROQ query, you're on the right track! To get unique subcategory paths as strings, you'll need to use array manipulation and the array::unique() function. Here's how to refactor your query:
export const conferencesAuthorHasWrittenFor = groq`
*[_type == 'author' && slug.current == $slug && archived == false][0]{
"conferencesWrittenFor": array::unique(
*[_type == 'post' && references(^._id)] {
"subcategory": subcategory->{title, 'slug': slug.current, "parentSlug": parent->slug.current, "parentTitle": parent->title}
}.subcategory[defined(@)]
| order(parentSlug, slug)
{"path": "/news/" + parentSlug + "/" + slug}
.path
)
}
`Here's what's happening:
.subcategory[defined(@)]- After projecting the subcategory objects, we access thesubcategoryfield and filter out anynullvalues using[defined(@)]String concatenation - In the next projection, we build your desired path format:
"/news/" + parentSlug + "/" + slug.path- This extracts just the path string from each object, giving you an array of strings instead of objectsarray::unique()- This wraps the entire expression to remove duplicates
The result will be a flat array of unique strings like:
["/news/tech/ai", "/news/design/ux", "/news/tech/web"]The GROQ Functions Reference documents array::unique() along with other useful array functions. You can also check out the Query Cheat Sheet for more examples of array manipulation patterns.
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.