Hey all - what’s the quickest way to batch delete all documents of a certain type? It looks like the `sanity` cli tool allows deletion of documents by ID but no ability to...

4 replies
Last updated: Jan 29, 2021
Hey all - what’s the quickest way to batch delete all documents of a certain type? It looks like the
sanity
cli tool allows deletion of documents by ID but no ability to delete by query?
AI Update

The Sanity CLI doesn't have a direct "delete by query" command, but there are several effective ways to batch delete documents of a certain type:

Using the CLI with a Pipeline

The most straightforward CLI approach is to query for document IDs and pipe them to the delete command. From this bulk deletion guide, here's the recommended one-liner:

sanity documents query "*[_type == 'myDocument']._id" --apiVersion 2021-03-25 
  | groq "*" -o ndjson 
  | join 
  | xargs sanity documents delete

What's happening here:

  • The query fetches all document IDs of your target type
  • GROQ CLI converts the output to ndjson format
  • The join command combines the IDs into a single string
  • xargs passes them to the delete command

Note: You'll need to install groq-cli (npm install -g groq-cli) and the author's Console.Join tool for this to work smoothly.

Using the JavaScript Client (More Reliable)

For better control and error handling, use @sanity/client in a Node script. While client.delete({query}) isn't supported, you can query first and then delete in batches:

import {createClient} from '@sanity/client'

const client = createClient({
  projectId: 'your-project-id',
  dataset: 'your-dataset',
  token: 'your-token-with-write-access',
  apiVersion: '2024-01-01',
  useCdn: false
})

async function batchDelete() {
  // Fetch all document IDs of the type you want to delete
  const ids = await client.fetch('*[_type == "yourDocumentType"]._id')
  
  // Delete in batches to avoid transaction limits
  const batchSize = 100
  for (let i = 0; i < ids.length; i += batchSize) {
    const batch = ids.slice(i, i + batchSize)
    const transaction = client.transaction()
    batch.forEach(id => transaction.delete(id))
    await transaction.commit()
    console.log(`Deleted ${Math.min(i + batchSize, ids.length)} of ${ids.length}`)
  }
}

batchDelete()

This approach from the community discussions gives you progress tracking and better error handling.

Important Considerations

  • Referential Integrity: Sanity prevents deletion of documents that are referenced elsewhere. You'll need to handle or remove those references first.
  • Token Permissions: Ensure your token has write access to the dataset.
  • Backup First: Consider exporting your dataset before bulk deletions using sanity dataset export.
  • Transaction Limits: Keep batch sizes reasonable (around 100 documents per transaction).

The JavaScript client approach is generally more reliable for large-scale deletions since you get better error handling, progress tracking, and can implement retry logic if needed.

I think you can (but don't use the CLI myself). See "Deleting multiple documents by query" here: https://www.sanity.io/docs/http-mutations
Hey
user A
thanks! I actually managed to just do a
sanity documents query
call to grab all of the relevant document IDs, pulled them into a text doc to massage the response down to space-separated IDs, then put them back into
sanity documents delete …
and it worked a charm 😄
Maybe not the proper programmatic way to do it, but good enough for what I need for now
Nice. Hey, if it worked, it was the right way. 🥳

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?