Created
August 29, 2020 07:16
-
-
Save kmelve/b02b0caf8e6ffbcb508beddca00a33c6 to your computer and use it in GitHub Desktop.
Migrate categories in an array field on sanity.io
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* eslint-disable no-console */ | |
import client from 'part:@sanity/base/client' | |
// Run this script with: `sanity exec --with-user-token migrations/migrateValues.js` | |
// | |
// This example shows how you may write a migration script that migrates a field value | |
// on a specific document type. | |
// This will migrate documents in batches of 100 and continue patching until no more documents are | |
// returned from the query. | |
// | |
// This script can safely be run, even if documents are being concurrently modified by others. | |
// If a document gets modified in the time between fetch => submit patch, this script will fail, | |
// but can safely be re-run multiple times until it eventually runs out of documents to migrate. | |
// A few things to note: | |
// - This script will exit if any of the mutations fail due to a revision mismatch (which means the | |
// document was edited between fetch => update) | |
// - The query must eventually return an empty set, or else this script will continue indefinitely | |
// Fetching documents that matches the precondition for the migration. | |
// NOTE: This query should eventually return an empty set of documents to mark the migration | |
// as complete | |
const fetchDocuments = () => | |
client.fetch(`*[_type == 'post' && "guides" in categories][0...100] {_id, _rev, categories}`) | |
const buildPatches = docs => | |
docs.map(doc => ({ | |
id: doc._id, | |
patch: { | |
set: {categories: [...doc.categories, 'guide'].filter(cat => cat !== "guides")}, | |
// this will cause the migration to fail if any of the documents has been | |
// modified since it was fetched. | |
ifRevisionID: doc._rev | |
} | |
})) | |
const createTransaction = patches => | |
patches.reduce((tx, patch) => tx.patch(patch.id, patch.patch), client.transaction()) | |
const commitTransaction = tx => tx.commit() | |
const migrateNextBatch = async () => { | |
const documents = await fetchDocuments() | |
const patches = buildPatches(documents) | |
if (patches.length === 0) { | |
console.log('No more documents to migrate!') | |
return null | |
} | |
console.log( | |
`Migrating batch:\n %s`, | |
patches.map(patch => `${patch.id} => ${JSON.stringify(patch.patch)}`).join('\n') | |
) | |
const transaction = createTransaction(patches) | |
await commitTransaction(transaction) | |
return migrateNextBatch() | |
} | |
migrateNextBatch().catch(err => { | |
console.error(err) | |
process.exit(1) | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment