
Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag storeGreat question! To group documents by a specific field dynamically in Sanity, you'll need to use the Structure Builder API with S.documentList() and GROQ filters.
However, there's an important limitation: GROQ can't project objects with dynamic keys. So you can't get exactly the format you showed with { "leadership": [], "radiologist": [] } directly from a query.
Here are your two best options:
If you make category a reference to a separate category document type instead of just a string, you can create a dynamic structure:
*[_type == 'category'] {
"category": name,
"results": *[
_type == "physician"
&& references(^._id)
]
}This gives you:
[
{
"category": "radiologist",
"results": [/* physicians */]
},
{
"category": "leadership",
"results": [/* physicians */]
}
]If you want to keep categories as strings, you'll need to list them explicitly:
{
"radiologist": *[_type == "physician" && category == "radiologist"],
"leadership": *[_type == "physician" && category == "leadership"]
}You can create filtered lists in your Studio desk structure:
S.documentTypeList('category')
.title('Posts by Category')
.child(categoryId =>
S.documentList()
.title('Physicians')
.filter('_type == "physician" && $categoryId == category')
.params({ categoryId })
)The reference approach is more flexible and maintainable since it automatically adapts when you add new categories. The hardcoded approach works but requires updating your query whenever categories change.
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