👋 Next.js Conf 2024: Come build, party, run, and connect with us! See all events

Querying for a specific item type within a document in Sanity.io

16 replies
Last updated: Aug 15, 2021
Or better yet how can I query ALL items of _type ?
Aug 15, 2021, 9:12 AM
*[_type == "limitedImage*"]*
*[_type == "image*"]*
*[_type == "whateveryourtypeis*"]*
Aug 15, 2021, 9:38 AM
This is not working as limitedImage is not a document but an item inside
Aug 15, 2021, 9:42 AM
an item inside what?
Aug 15, 2021, 3:17 PM
I’m not sure I understand your issue 🤔
Aug 15, 2021, 3:17 PM
An item inside document
Aug 15, 2021, 3:18 PM
The type I'm trying to batch edit is an item inside a document, not a document itself
Aug 15, 2021, 3:18 PM
ah, well I guess you want to get every document and test if the type exists inside of it?
Aug 15, 2021, 3:19 PM
Yeah anywhere in the document,
I couldn't find a query for this
Aug 15, 2021, 3:20 PM
Or documentation
Aug 15, 2021, 3:20 PM
do you know the field the _type is used on?
Aug 15, 2021, 3:20 PM
*[]
gets every document and returns every field from each of those documents
Aug 15, 2021, 3:22 PM
you could then loop over that response, traversing every field until you find your type
Aug 15, 2021, 3:23 PM
It varies how deep it is, there's no consistence
Aug 15, 2021, 3:24 PM
Ok, so this a script I used to update all the values of a
link
object (there was an issue with a content migration where where we needed to find all instances of
url
and changed it to be
href
)
This might be a good starting point for you?

/**
 * Use to check for link 'url' properties that have been migrated incorrectly.
 * Run this script with: `sanity exec --with-user-token scripts/migrate/patchLink.ts`
 */

 import sanityClient from 'part:@sanity/base/client';
 import consola from 'consola';
 
 const client = sanityClient.withConfig({
   dataset: 'dev',
   apiVersion: 'v2020-03-15',
 });
 
 const patchDocument = (obj, updateDocument) => {
   if (obj !== null) {
     Object.entries(obj).forEach(([key, value]) => {
       // find the _type you're looking for
       if (key === '_type' && value === 'link') {
         // do what you need to to the data of that object 
         if (obj.url) {
           if (!obj.href) {
             obj.href = obj.url;
           }

           delete obj.url;

           updateDocument = true;
         }
       } else if (typeof value === 'object') {
         updateDocument = patchDocument(value, updateDocument);
       }
     });
   }
 
   return updateDocument;
 };
 
 const runProcess = async () => {
   const allDocuments = await client.fetch(`*[]`);
 
   let documentsUpdated = 0;
   const concurrency = 50; // keep under sanity rate limit
 
   console.time('patchLink');
 
   while (allDocuments.length) {
     await Promise.all(
       allDocuments.splice(0, concurrency).map(async doc => {
         const updateDocument = patchDocument(doc, false);
 
         if (updateDocument) {
           const docTitle =
             (doc._type == 'profile' && `${doc.firstName} ${doc.lastName}`) || doc.title?.en_GB || doc.title || doc._id;
           consola.success(`Fixing (${doc._type}) ${docTitle}`);
 
           await client.createOrReplace(doc);
 
           documentsUpdated++;
         }
       })
     );
   }
 
   <http://consola.info|consola.info>(`Number of documents updated: ${documentsUpdated}`);
   console.timeEnd('patchLink');
 };
 
 runProcess();
 
Aug 15, 2021, 3:29 PM
That code could probably be much nicer, but it did the trick.. though it is slow (took ~5mins to run) as it had to dive through so many documents and levels
Aug 15, 2021, 3:30 PM
Thanks I'll give it a check soon!
Aug 15, 2021, 3:31 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?