👀 See Sanity in action: Watch product demo now →

How to get a List / Array of IDs that are Referenced by Documents

12 replies
Last updated: Jun 25, 2022
A
page
doc can have multiples
form
references, but they could be deeply nested in any number of places. How do I get a list of the
form
references on the
page
?
references() hasn’t worked for me here. I don’t want a list of documents that reference an id. I want a list of ids that are referenced.
Jun 24, 2022, 4:13 PM
Seems like Sanity needs a referencedBy() function.
I need this:
*[_type == “form” && referencedBy(“id”)]{

}
Jun 24, 2022, 4:15 PM
But I feel like I’m missing something. This is a hugely common use case
Jun 24, 2022, 4:16 PM
I have two document types. One is called "resource" and is a specific kind of page.
Another type is called "localProfessional" and is information about a vendor.

If I do


*[_type=="localProfessional"]{
  vendorName
  "matchingResource": *[_type=='resource' && references(^._id) && !(_id in path("drafts.**"))]{ 
  	  _id,
      title
	}
}
I can see which Resource pages are calling up that document. In other words, I can get the IDs of documents referencing my localProfessional. I can see what the localProfessionals are referenced by.

I don't think it's openly recursive where it's going to find things way down deep; localProfessional are references in a field right off the top called featuredLocalProfessionals
😃
The image attached is an example of what returns. In the absense of it being genuinely recursive I wonder if you could form a query programmatically that would scrub to a prescribed depth. I am also curious about the modeling that would keep them nested down that far.
Jun 24, 2022, 4:59 PM
user S
thx for the input! in my case (but relating it to your example), I need an array of resources that localProfessional references, not an array of resources referencing the localProfessional
Jun 24, 2022, 6:05 PM
In my Studio the reference is made through an array in one direction, so the localProfessional in Studio does no referencing of its own. The result I have a above is just to climb backwards up the hole to see who is calling it.
I don't think I have a truly bidirectional analogue for your use case. Is there a way to have a peek at the relevant schema for yours? It's hurting my head a bit talking around it haha
Jun 24, 2022, 6:24 PM
The full schema would be 5000 lines or so, but this is the problem:
If my data was flat, this would be easy:

*[_type=="localProfessional"]{
  vendorName
  resources[]{ 
    _id,
    title
	}
}
The issue is that I use a page builder where the page is constructed using modules. But the modules are able to reference all sorts of data. So the data structure changes from page to page. I would have to write some crazy query like this:

*[_type=="localProfessional"]{
  vendorName,
  stuff{
    stuff{
      moreStuff{
        resources[]{ 
          _id,
          title
        }
      }
    },
    otherStuff{
      moreStuff{
        resources[]{ 
          _id,
          title
        }
      }
    }
  },
  moreStuff{
    otherStuff{
      resources[]{ 
        _id,
        title
      }
    },
    stuff{
      deeperStuff{
        resources[]{ 
          _id,
          title
        }
      }
    }
  }
}

Jun 24, 2022, 6:34 PM
In plain english I need a query to solve “give me all of the resources in this doc”
Jun 24, 2022, 6:35 PM
I can’t believe this isn’t possible in Sanity, so I feel I’m just missing something obvious
Jun 24, 2022, 6:35 PM
Ah, I see. Yeah I definitely just was thinking along the lines of a tiny snippet, so no worries.
I tried doing *[_type="form" && _type="reference"] thinking I was clever but it's not recognized.

I think part of the issue is GROQ has a lot in common with object notation and JavaScript at large, where generally speaking there needs to be a path carved.

Leaving it to "go find this one piece in a maze at every possible depth" seems a little counter to why it exists.

That said, I'm clearly not an expert. I would say if you know of a finite depth that exists, there are conditional select subqueries that can navigate the changes between pages. I know what you're saying about it looking crazy but I've seen far crazier and it's likely to still be pretty performant still, and if it's the difference between your stuff working or not it may come down to it.

Hopefully someone more knowledgeable can help you. You mentioned it being hugely common; on other page builder setups what have you seen that came close when it came time for them to navigate similar situations?
Jun 24, 2022, 7:06 PM
I was able to finally figure out how to retrieve an array of the form ids:

 *[_id == $id]{
    'forms': *[_type == "form"]{
      ...select(
        $id in *[_type == "page" && references(^._id)]._id => {
          _id
        }
      )
    }
  }{
    forms[defined(_id)]
  }[0].forms{_id}._id
brutal
Jun 24, 2022, 10:27 PM
I certainly appreciate your commitment! I followed that till the end. I'm going to see if I can reread the high performance docs tomorrow and compare and contrast and identify any opportunities to squeeze any more juice out
Jun 25, 2022, 2:22 AM
Speaking generally, what kind of format do your page IDs have? Are they the gangly uuid-looking ones by default? I may have an idea...
Jun 25, 2022, 1:39 PM

Sanity.io – build remarkable experiences at scale

Sanity is a customizable solution that treats content as data to power your digital business. Free to get started, and pay-as-you-go on all plans.