How to select() from referenced values with multiple document types in GROQ?
Yes! GROQ has a select() function that's perfect for this exact scenario. It's a much cleaner way to handle conditional field selection from references that could point to different document types.
Instead of your current approach (which does work but relies on duplicate field names silently overwriting each other), you can use select() like this:
*[_type == "story" && !(_id in path('drafts.**'))] | order(publicationDate desc) {
"references": references[] {
"title": select(
defined(reference->name) => reference->name,
defined(reference->title) => reference->title
)
}
}The select() function evaluates conditions in order and returns the first truthy value. Each condition follows the pattern condition => value.
If you know the specific document types, you can be even more explicit:
*[_type == "story" && !(_id in path('drafts.**'))] | order(publicationDate desc) {
"references": references[] {
"title": select(
reference->_type == "typeA" => reference->name,
reference->_type == "typeB" => reference->title,
"Untitled" // optional fallback
)
}
}Why this is better than your current approach:
- Explicit intent: Makes it clear you're handling different document types
- More maintainable: Easier to understand and modify later
- Scales better: Easy to add more document types or conditions
- No hidden behavior: Your current approach works because GROQ allows duplicate keys in projections with the last value winning, but this is implicit behavior that could confuse other developers
The select() function stops evaluating as soon as it finds a matching condition, so it's also efficient. You can add as many conditions as you need, and always include a fallback value at the end for safety.
Show original thread5 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.