Sorting null values in descending order in Groq
I understand your frustration! The behavior you're experiencing with null/undefined values in GROQ sorting is indeed tricky.
While the official documentation doesn't explicitly detail how null/undefined values are sorted, the issue you're encountering is real. The solution is to use the defined() function in combination with multiple sort expressions in your order() function.
Here's the approach that should work for you:
*[_type == "yourType"] | order(defined(search_priority) desc, search_priority desc)This works by creating a two-level sort:
- First, it sorts by whether
search_priorityis defined (documents where the field exists and isn't null) - Then, it sorts by the actual
search_priorityvalue
So you should get documents with values 10, 5, 0 first, followed by documents where search_priority is null or undefined.
If you want the null/undefined values at the end with ascending numeric order instead, you'd use:
*[_type == "yourType"] | order(defined(search_priority) desc, search_priority asc)This gives you: 0, 5, 10, then null/undefined.
Alternative approach using coalesce()
You could also use the coalesce() function to provide a default value for null/undefined cases:
*[_type == "yourType"] | order(coalesce(search_priority, -1) desc)This treats null/undefined as -1, so they'll sort after 0. You can adjust the fallback value (-1 in this example) to control where null/undefined documents appear in your results.
The key insight is that GROQ's order() function accepts multiple sort expressions separated by commas, and it will use them as primary/secondary sort keys - which is exactly what you need to handle those null values while keeping all your documents in the results.
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.