Go Behind the Experience to see how Tecovas brings the West to life with Sanity 🤠 July 18th

Filtering array of references in GROQ for Sanity schema design

7 replies
Last updated: Jun 18, 2024
Anyone know the best way to filter an array of references based on the reference content? I've managed to solve this using pipes (see below), but it seems unwieldy. Is this kind of thing just a GROQ no-go that should be solved with better schema design/architecture?

*[_type=="myDocument"] {
  arrayOfRefs[]->{
    title
  }
} | {
  arrayOfRefs[title == "Some Title"]
}
It seems intuitive that something along the lines of this should be possible:

// NOT VALID GROQ!
*[_type=="myDocument"] {
  arrayOfRefs[]->[title=="Some Title"]{
    title
  }
}
Jun 14, 2024, 8:11 PM
Try something like:
*[_type=="myDocument"] {
  arrayOfRefs[@->title=="Some Title"]{
    title
  }
}
Jun 14, 2024, 8:14 PM
Wow, that is perfect
Jun 14, 2024, 8:15 PM
Thank you!
Jun 14, 2024, 8:15 PM
Just wanted to put kudos in here for
user M
, who so often comes up with a sensible good answer :)
I did come up with at least one other way to write it, but his is clear and straightforward -- that @-> is a good thing to realize and know....
Jun 15, 2024, 9:34 PM
just a small further note, as I was at first mislead on this by the statement that keeps recurring that 'Sanity references are bi-directional'.
I think they are not -- what is true is that they can be queried in Groq to discover the backwards as well as forwards relationships.


user M
's solution is a fine shorthand, and works forwards -- where you recognize the @ is referring to the arrayOfRefs, each item in turn that it contains, dereferenced by the -> to the document this ref points to, building up the result for the select.
This alternate is a 'backwards' method, which gets the same kind of result. In this case, I have a visible locale type holding all of them, and a locales array in the schema for the ones a given document may have chosen:

"locs_areas" : *[_type == 'locale' && _id in ^.locales[]._ref ] { area },

I like
user M
's way, because it gets right to the point -- and is probably easier for any query optimizer
Jun 17, 2024, 5:47 AM
+
Jun 18, 2024, 5:11 AM
Hmm - small Monday correction after looking again -- I suspect you need a dereferencing arrow on the example,
user M
, as the array is of references, no?
So it would look like (and tested similar:) ):

*[_type=="myDocument"] {
  arrayOfRefs[@->title=="Some Title"]->{
    title
  }
}
It's always the details that get you, right ? Why Studio Vision is so valuable... :)
Jun 18, 2024, 5:56 AM

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.

Was this answer helpful?