How to get unique values in a GROQ query?
Yes, you can get unique/distinct values in GROQ, but not quite the way you've written it. The unique() function isn't a filter that you apply inline within the document filter expression.
GROQ provides the array::unique() function that works on arrays. Here's how to use it:
For unique values from a field across documents:
array::unique(*[_type == 'route'].url)This collects all url values from route documents and returns only the unique ones as an array.
You can also pipe into it:
*[_type == 'route'].url | array::unique()Both approaches give you the same result - an array of unique URL values.
Important limitation: There's no built-in way to filter documents by unique field values directly in the filter expression like *[_type == 'route' && unique(url)]. The array::unique() function works on arrays, not as a filter constraint.
If you need full documents with unique URLs:
You'll need to handle this differently depending on your use case:
- Get unique URLs first, then fetch documents separately based on those URLs
- Fetch all documents and deduplicate in your application code based on the URL field
- Restructure your data model if you frequently need to query by unique values
The array::unique() function was added in September 2022 as part of GROQ spec updates to help with exactly this kind of scenario - finding distinct values across your content. It removes duplicate values from an array, with the caveat that it only works on values that can be compared for equality (strings, numbers, booleans, and null).
If you share more about what you're trying to achieve - like whether you need just a list of unique URLs, or the first/last document with each unique URL - I can suggest a more specific approach!
Show original thread16 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.