How to Write a Filter Query
26 replies
Last updated: Jun 8, 2020
S
Hello amazing Sanity people 🌞 ! I am doing my head in trying to figure out how to write a filter query.I have a document with an array called
Maybe this is actually very simple, but I can’t seem to work it out…
primary
primaryis an array of
itemobjects.In item, instead of getting a list of all sections, I only want to see those which are not already referenced by my document.
Maybe this is actually very simple, but I can’t seem to work it out…
name: 'item', title: 'Item', type: 'object', fields: [ { name: 'section', title: 'Section', type: 'reference', to: { type: 'section' }, options: { filter: ({ document, parent, parentPath }) => { console.log(document._id) return { filter: '!(^._id in *[_id==$document].primary[])', params: { document: document._id } } } } } ]
May 28, 2020, 1:33 PM
J
Could it be as simple as
!references($document)?
May 28, 2020, 1:37 PM
S
I wish! That would only check if
sectionhas a direct reference to
documentbut not if
documenthas an array which has a reference to
section
May 28, 2020, 1:39 PM
S
Running
*[_id==$document][0].primary[].section[]in Vision gives me
May 28, 2020, 1:43 PM
S
is
^._idreferring to the potential `section`s
_idin this case?
May 28, 2020, 1:44 PM
S
The updated filter is:
Still not producing any results :'(
^._id in *[_id==$document][0].primary[].section[]
May 28, 2020, 1:45 PM
J
Hm, something tells me you're hitting some array travelsal bug in the query handling. I've seen similar queries failing due to that
May 28, 2020, 1:54 PM
S
aha
May 28, 2020, 1:54 PM
J
For what it's worth, it should be
^._id in *[_id==$document][0].primary[].section[]._ref
May 28, 2020, 1:56 PM
J
(you just want an array of strings)
May 28, 2020, 1:57 PM
S
Hmm… if I run
I’m just getting every single document in my store
*["f6529b36-sectionID" in *[_id==$document][0].primary[].section[]._ref]
May 28, 2020, 2:01 PM
S
Very odd
May 28, 2020, 2:02 PM
S
Because what you sent me does give me an array of strings
May 28, 2020, 2:03 PM
S
I would have assumed that
*["string" in []]would produce the right results
May 28, 2020, 2:03 PM
S
But maybe there is a traversal bug of some sort
May 28, 2020, 2:04 PM
S
Have you ever tried to filter out a reference that’s already added to a list?
May 28, 2020, 2:13 PM
J
Would unique validation be of any helo? https://www.sanity.io/docs/array-type#unique()-49ee9907c730
May 28, 2020, 3:58 PM
J
user C
Just tested this to filter out refs already added to the list, seems to work:options: { filter: ({document}) => { const ids = document.people.map(person => person._ref).filter(Boolean) return { filter: '!(_id in $ids)', params: {ids} } } }
May 28, 2020, 4:09 PM
S
🙏
May 28, 2020, 4:21 PM
S
Hero! And all it took was some javascript magic! Thank you so much Jørn! Your second example was perfect… it actually checks the existence in more than one array!
May 28, 2020, 4:22 PM
S
I ♥️ Sanity
May 28, 2020, 4:23 PM
J
❤️
May 28, 2020, 4:48 PM
J
Hi still fiddelng with this is the code below allong the correct lines? Its not working at the moment?
Jun 8, 2020, 2:17 PM
J
export default { name: 'single', title: 'Single', type: 'document', fields: [ { name: 'name', title: 'Name', type: 'string', validation: (Rule) => Rule.required(), }, { name: 'tracks', title: 'Tracks', type: 'array', of: [ { type: 'reference', to: [{ type: 'track' }], }, ], options: { filter: ({ document }) => { const ids = document.track.map((trk) => trk._ref).filter(Boolean) return { filter: '!(_id in $ids)', params: { ids }, } }, }, validation: (Rule) => Rule.required(), }, ], }
Jun 8, 2020, 2:17 PM
J
Think you're missing an s? Should be
document.tracks?
Jun 8, 2020, 2:55 PM
J
Thanks good spot
Jun 8, 2020, 6:24 PM
J
Easy to miss 😅
Jun 8, 2020, 7:00 PM
Sanity– build remarkable experiences at scale
Sanity is a modern headless CMS that treats content as data to power your digital business. Free to get started, and pay-as-you-go on all plans.