Sorting null values in descending order in Groq

2 replies
Last updated: May 30, 2023
Hi all, I have a problem with a sort.
I have a field called search_priority, which is 0, 5 or 10 - or it can be null or undefined.
I do
| order(search_priority desc)
and this doesn’t work as expected.If I eliminate the documents that doesn’t have search_priority set it works fine, but I would like all the documents, just ordered.
Is null interfering somehow? Shouldn’t it be 10, 5, 0, null – or is “null” considered a string, so it becomes null, 10, 5, 0 ?
AI Update

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:

  1. First, it sorts by whether search_priority is defined (documents where the field exists and isn't null)
  2. Then, it sorts by the actual search_priority value

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.

Hi Rune. When sorting in descending order,
null
will appear first. To push the
null
values to the end of the sort, we can use
coalesce()
to assign a non-
null
value for the purposes of the sort. The key is to assign a value that will fit into the sort properly.
For numbers,
| order(coalesce(search_priority, -1) desc)
should treat
null
values as
-1
, putting them “lower” than search_priorities of
0
and higher. Feel free to change
-1
to a more negative number if there’s any chance that
search_priority
could be given a negative value in the future. The key is to ensure the
coalesce
fallback is always the lowest number.
Note that this does not change the
search_priority
values in any way. It is strictly in the context of the
order()
function.
Thanks, that worked! Probably a good idea to put that one in the Groq Cheat Sheet 🙂

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?