Unlock seamless workflows and faster delivery with our latest releases - Join the deep dive

Querying multiple documents with dereferenced fields in a single query

12 replies
Last updated: Aug 16, 2022
Might be a silly question, but what am I doing wrong here?
{
  "error": {
    "description": "expected '}' following object body",
    "end": 65,
    "query": "*[_type in ["banner", "footer"]] { _type == "footer" => { ... } }",
    "start": 40,
    "type": "queryParseError"
  }
}
All I'm trying to do is fetch multiple documents in a single query, while being able to define the fields for each
Aug 16, 2022, 11:02 AM
Odd, that looks okay.
Aug 16, 2022, 11:21 AM
could you post your query just in case?
Aug 16, 2022, 12:12 PM
Sure - Here's all the logic simplified:
import { createClient } from "next-sanity";

const sanityClient = createClient({
  dataset: process.env.NEXT_PUBLIC_SANITY_DATASET || "production",
  projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID || "",
  apiVersion: "2021-10-21",
  useCdn: process.env.NODE_ENV === "production",
});

const res = await sanityClient.fetch(`*[_type in ["banner", "footer"]] {
  _type == "footer" => {
    ...
  }
}`);
Aug 16, 2022, 12:18 PM
Alternatively, do you perhaps have some query to suggest for fetching multiple documents while dereferencing their content?
e.g.

*[_type == "footer"] {
  ...,
  socials[] {
    ...,
    social->
  }
}
But applied for multiple documents in a single query
Aug 16, 2022, 12:23 PM
What exactly are you trying to do, if I may ask?
Aug 16, 2022, 12:36 PM
Just need to dereference documents within documents so their content can be accessible
Aug 16, 2022, 12:38 PM
yes there is a way to do it, but I cannot help unless I understand/have an example to work with šŸ™‚This
wonderful groq tutorial (interactive) by
user B
can help you quite a bit as well as this article in our docs about groq
Aug 16, 2022, 12:46 PM
Thanks for the links, it looks pretty great but it doesn't really touch on what I'm looking for
Essentially, let's imagine I have a document that references another document. When querying it we don't receive the actual document, but rather the reference of it. Instead, what I would need is the actual document dereferenced.

In other words if this is the schema:

export default {
  name: "footer",
  title: "Footer",
  type: "document",
  fields: [
    {
      name: "title",
      title: "Title",
      type: "string",
    },
    {
      name: "socials",
      title: "Socials",
      type: "array",
      of: [
        {
          name: "social",
          title: "Social",
          type: "reference",
          to: { type: "social" },
        },
      ],
    },
  ],
};
To get the
footer
document with the dereferenced
social
document I'd need to use this query:
*[_type == "footer"] {
  ...,
  socials[] {
    ...,
    social->
  }
}
Now, what would I do if I need to do it for multiple documents? I can of course write multiple queries but for effectiveness I was looking for some way to fetch them all in one, e.g.:

*[_type in [ footer, otherDocument ]]
Only problem with that, is I'm not sure how I'd go about setting up the fields for each as the query above on the thread doesn't seem to work

Let me know if that clarifies, can retry in different terms if not
šŸ™‚
Aug 16, 2022, 1:07 PM
Since you need to explicitly dereference you fields, I think it would be better to go about it this way:
{
  "footer": *[_type =='footer'] {...//whatever fields you need to dereference},
  "otherDocument": *[_type == 'otherDocument']{...//whatever fields you need to dereference}
}
That is, unless the fields you'll be dereferencing are exactly the same in each document type.
Aug 16, 2022, 4:54 PM
Spot on! Wasn't aware of that syntax, that's very handy - Thank you!
Aug 16, 2022, 9:00 PM
Spot on! Wasn't aware of that syntax, that's very handy - Thank you!
Aug 16, 2022, 9:04 PM
You're welcome!
Aug 16, 2022, 9:12 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.

Was this answer helpful?