How to Write a Filter Query
I can help you filter out already-referenced sections from your reference field! The issue with your current query is the syntax - you're trying to access the parent document's array, but the approach needs adjustment.
Here's the corrected solution:
{
name: 'section',
title: 'Section',
type: 'reference',
to: { type: 'section' },
options: {
filter: ({ document }) => {
// Get all section IDs already referenced in the primary array
const referencedIds = document.primary
?.map(item => item.section?._ref)
.filter(Boolean) || []
return {
filter: '!(_id in $referencedIds)',
params: {
referencedIds
}
}
}
}
}What's happening here:
Extract referenced IDs in JavaScript: Instead of trying to do this purely in GROQ, we extract the
_refvalues from theprimaryarray items in the filter function itself. This is more reliable since you have direct access to the document object.Simple GROQ filter: The GROQ filter
!(_id in $referencedIds)checks if the current section's_idis NOT in the array of already-referenced IDs.Pass as params: We pass the array of IDs as a parameter to the GROQ query.
Important note: The filter function re-runs when the document changes, so as you add sections to your primary array, they'll automatically disappear from the available options in other items.
Making it reusable:
You can extract this into a utility function to keep your code DRY, as shown in this community example:
// utils/getFilter.js
export const getFilter = (document, field, refField = '_ref') => {
const existingEntries = document[field]
?.map(item => item[refField])
.filter(Boolean) || []
return {
filter: '!(_id in $existingEntries)',
params: {
existingEntries
}
}
}
// Then in your schema:
options: {
filter: ({ document }) => {
const referencedIds = document.primary
?.map(item => item.section?._ref)
.filter(Boolean) || []
return {
filter: '!(_id in $referencedIds)',
params: { referencedIds }
}
}
}This is a common pattern when building navigation menus, related content pickers, or any scenario where you want to avoid duplicate references in an array!
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.