πŸ‘€ Our most exciting product launch yet πŸš€ Join us May 8th for Sanity Connect

Batch remove a field

By Geoff Ball

Script to batch remove a field from all documents that match a GROQ query

removeField.js

/**
 * THIS SCRIPT DELETES DATA!
 *
 * To use this script:
 * 1. Put this script in your studio folder
 * 2. Set FIELD_TO_REMOVE to the field you want to remove (using dot notation to drill down)
 * 3. Optionally, modify the GROQ filter in fetchDocuments() to further restrict the query, if needed
 * 4. Run `sanity dataset export` to backup your dataset before modifying a bunch of documents
 * 5. Run `sanity exec removeField.js --with-user-token` in your terminal to delete the field from all matched documents
 */

import sanityClient from 'part:@sanity/base/client'

const client = sanityClient.withConfig({ apiVersion: '2021-12-17' })

const FIELD_TO_REMOVE = 'metadata.location'

const fetchDocuments = () => client.fetch(`*[${FIELD_TO_REMOVE} != null][0...10] {_id, _rev}`)

const buildPatches = docs => docs.map(doc => ({
  id: doc._id,
  patch: {
    unset: [FIELD_TO_REMOVE],
    ifRevisionID: doc._rev
  }
}));

const createTransaction = patches =>
  patches.reduce((tx, patch) => tx.patch(patch.id, patch.patch), client.transaction())

const commitTransaction = tx => tx.commit()

const editNextBatch = async () => {
  const documents = await fetchDocuments()
  const patches = buildPatches(documents)

  if (patches.length === 0) {
    console.log('No more documents to unset!')
    return null
  }

  console.log(
    `Editing batch:\n %s`,
    patches.map(patch => `${patch.id} => ${JSON.stringify(patch.patch)}`).join('\n')
  )
  const transaction = createTransaction(patches)
  await commitTransaction(transaction)
  return editNextBatch()
}

editNextBatch().catch(err => {
  console.error(err)
  process.exit(1)
})

This script lets you unset/remove a field from documents that match a GROQ query. For example, this might be used to quickly remove sensitive data (in this code, we're removing metadata.location).

It can be run from your terminal in a studio folder using sanity exec removeField.js --with-user-token.

Note that this script deletes data so it is wise to export your dataset and/or test your script on a non-production dataset before running this in production.

Contributor

Other schemas by author

Matching the end of a string in GROQ

GROQ doesn't yet include a function to match the end of a string, but we can simulate it by splitting our string on our term.

Geoff Ball
Go to Matching the end of a string in GROQ