
Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag storeYou can definitely do this in GROQ! The key is to filter the array after dereferencing. You'll want to use a projection with array filtering syntax on the dereferenced objects.
Here's how to structure your query:
*[_type == 'page'] {
whatsOn {
'results': selected[]->[@.endDate >= '2022-01-06' || @.date >= '2022-01-06']
}
} | order(_updatedAt desc)[0]Let me break down what's happening:
selected[]-> dereferences all items in your selected array[@.endDate >= '2022-01-06' || @.date >= '2022-01-06'] filters the dereferenced array@ refers to the current element in the array being filtered|| (OR) operator checks either conditionHowever, if you want to handle the conditional logic more explicitly (checking endDate first if it exists, otherwise falling back to date), you can use the defined() function:
*[_type == 'page'] {
whatsOn {
'results': selected[]->[@.endDate >= '2022-01-06' || (!defined(@.endDate) && @.date >= '2022-01-06')]
}
} | order(_updatedAt desc)[0]This ensures that if endDate exists and passes the date check, it includes the event. If endDate doesn't exist, it falls back to checking date.
Or, for a cleaner approach using the coalesce operator:
*[_type == 'page'] {
whatsOn {
'results': selected[]->[@.endDate >= '2022-01-06' || coalesce(@.endDate, @.date) >= '2022-01-06']
}
} | order(_updatedAt desc)[0]The coalesce() function returns the first non-null value, so it'll use endDate if it exists, otherwise date.
Pro tip: Instead of hardcoding the date, you can use the now() function to always compare against the current date:
*[_type == 'page'] {
whatsOn {
'results': selected[]->[@.endDate >= now() || coalesce(@.endDate, @.date) >= now()]
}
} | order(_updatedAt desc)[0]This way your query automatically filters out past events without needing to update the date string! The pipeline components documentation has more details on how filtering works within projections.
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