sanitygroq

Limit array of references to documents that have not been referenced yet


I have a "reference selector" (i.e. a module where editors can choose documents to reference) but I want to limit the results to the documents that have not been referenced yet.

This is the schema of my reference selector that is used inside another document:

export default {
  title: 'Project Selector',
  name: 'projectSelector',
  type: 'object',
  fields: [
    {
      title: 'Project',
      name: 'project',
      type: 'reference',
      to: [
        { type: 'project' }
      ],
      options: {
        filter: // What does my filter need to look like?
      }
    }
  ]
}

export default {
  title: 'Home Page',
  name: 'homePage',
  type: 'document',
  fields: [
    {
       title: 'Projects',
       name: 'projectsGrid',
       type: 'array',
       of: [
         { type: 'projectSelector' }
       ],
    },
  ]
}

Please note, the projectSelector object and the homePage document do not share any parent<>child relationship.


Solution

  • As long as we're talking about selecting documents that haven't been selected yet in that array, I would approach it with something like:

    options: {
      filter: ({ document }) => {
        const refList = document?.projectsGrid.map(item => {
          return item?.project?._ref
        })
        
        return {
          filter: '!(@._id in $list) && !(_id in path("drafts.**"))',
          params: { list: refList }
        }
      }
    },
    

    This should map over the existing references, return the _refs, and then consult that list when new references are added to filter them out.