Best practices for modeling and querying recursively nested documents in Sanity.io.

6 replies
Last updated: Dec 5, 2022
I’m sure this has been asked a bunch of times, but what’s the best solution for modelling a recursively nested document. So for example a “region” content type that could have any number of children or grandchildren to achieve a nested document structure like this:
UK => England => Oxfordshire
,
UK => Gibraltar
or
USA => Washington
Dec 2, 2022, 8:32 AM
Would something like this be sufficient?

https://www.sanity.io/guides/parent-child-taxonomy
Dec 2, 2022, 8:34 AM
I have setup a parent reference field to the same document.
What’s the best way to query a recursively nested referenced documents?
Dec 2, 2022, 9:54 AM
That guide is how I’d do it!
If you’re querying with GROQ, you can use the
references()
function to find other documents that reference a given _id.
So you could query for the
England
document and all documents that have it as their parent reference children like this:
*[title == "England"][0]{
  title,
  "children": *[references(_id)]{
    title
  }
}
Dec 2, 2022, 5:33 PM
Thanks for the feedback Right now I am querying the the document tree in both directions like this:
{
  "topDown": *[_type == "region" && name == "Taiwan"][0] {
    name,
    "children": *[_type == "region" && references(^._id)][0] {
      name,
      "children": *[_type == "region" && references(^._id)][0] {
        name,
        "children": *[_type == "region" && references(^._id)][0] {
          name,
        },
      },
    },
  },
  "downUp": *[_type == "region" && name == "Xinyi"][0] {
    name,
    parent -> {
      name,
      parent -> {
        name,
        parent -> {
          name,
        },
      },
    },
  },
}
…and that’s getting overlay complex and each nested document level would get more complicated. I was wondering if there’s any nicer ways to do this kind of recursive querying.

It’s only going to be for generating URLs and breadcrumbs, so not super critical
Dec 4, 2022, 2:55 PM
I see!
There’s no way to do a recursive query like this, unfortunately. You need to dig down and resolve each one.

In this instance, do
topDown
and
downUp
return the same data, but in reverse order? If so, do you need both?
Dec 5, 2022, 7:35 AM
Also if you know explicitly which field will contain the parent reference, this query might be faster:
"children": *[_type == "region" && parent._ref == ^._id]
Dec 5, 2022, 7:36 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?