How to group Sanity documents by a specific field value?

6 replies
Last updated: Oct 22, 2021
Hello guys, I need a little help about how I can group a document by a specific field. For example, I have
physician
document where I have
category
string filed which can be leadership, radiologist etc. I would like a result where I can have
{
"leadership": [],
"radiologist": []
}
AI Update

Great 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 */]
  }
]

Option 2: Hardcode Categories in Your Query

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"]
}

For Studio Structure Builder

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.

Show original thread
6 replies
Hey User! Just to clarify, are you trying to get the 'leadership' list to show all doctors whose category is leadership? What kind of schema is
category
?
So, I have a
physician
document where I have sample data like the following
[
  {
    "category": "radiologist",
    "name": "J. Michael Barraza, Jr., MD"
  },
  {
    "category": "leadership",
    "name": "User, M.D."
  },
  {
    "category": "leadership",
    "name": "User, M.D"
  }
]
I like to have a result that will be grouped by its category. So I would like to have an output that should be like

{ radiologist: [ 
{ category: 'radiologist', name: 'J. Michael Barraza, Jr., MD' } 
  ],
  leadership: [ 
{ category: 'leadership', name: 'User, M.D.' },
{ category: 'leadership', name: 'User, M.D' } 
    ] 
}
you can do a subquery like this:
client.fetch(`{
  "radiologist": *[category == "radiologist"],
  "leadership": *[category == "leadership"],
}`)
but what if I don’t know what user will give me input. As I said these are just string. I just would like this to be dynmic.
Ah, so this is for a search query, i.e searching for a person named Scott? If you have each category as a reference instead of a string, it’d be easier. Say your data looks like this instead

[
  "_type": "physician",
  "category": {
    "_type": "reference",
    "_ref": "abc123"
  },
  "name": "J. Michael Barraza, Jr., MD",
},
{
  "_type": "category",
  "_id": "abc123",
  "name": "radiologist"
}
]
Then you can query based on category

*[_type == 'category'] {
  "category": name,
  "results": *[
    _type == "physician"
    && name match "Mic*"
    && references(^._id)
  ]
}
The result will look like this


[{
  "category": "radiologist",
  "results": [
    {
      name: "J. Michael Barraza, Jr., MD",
    }
  ]
}, {
  /* other categories */
}]
AFAIK you can’t project an object with dynamic keys, so this is the closest to your ideal results — I might be wrong though.

Without a category, you can still query, but it requires listing all categories in advance, like the query I shared above.

This is a working example in groq.dev:

https://groq.dev/3GA9zOXffsuJcE9IfuB7wi
Yeah that’s what I thought at first to create a category document type. But I was wondering if I can group with just string field. Thank you

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.

Was this answer helpful?