Knut Melvær
Knut runs developer relations at Sanity.io
This migration scripts lets you migrate documents to a new type.
import client from "part:@sanity/base/client";
const OLD_TYPE = "movie";
const NEW_TYPE = "film";
const fetchDocuments = () =>
client.fetch(
`*[_type == $oldType][0...10] {..., "incomingReferences": *[references(^._id)]{...}}`,
{ oldType: OLD_TYPE }
);
const buildMutations = docs => {
const mutations = [];
docs.forEach(doc => {
console.log("movie", doc._id);
// Updating an document _type field isn't allowed, we have to create a new and delete the old
const newDocId = `${doc._id}-migrated`;
const newDocument = { ...doc, ...{ _id: newDocId, _type: NEW_TYPE } };
delete newDocument.incomingReferences;
delete newDocument._rev;
mutations.push({ create: newDocument });
// Patch each of the incoming references
doc.incomingReferences.forEach(referencingDocument => {
console.log("ref", referencingDocument._id);
// ⚠️ We're assuming the field is named the same as the type!
// There might be another structure involved, perhaps an array, that needs patching
const updatedReference = {
[NEW_TYPE]: {
_ref: newDocId,
_type: "reference"
}
};
mutations.push({
id: referencingDocument._id,
patch: {
set: updatedReference,
unset: [OLD_TYPE],
ifRevisionID: referencingDocument._rev
}
});
});
// Apply the delete mutation after references have been changed
mutations.push({ delete: doc._id });
});
return mutations.filter(Boolean);
};
const createTransaction = mutations => {
return mutations.reduce((tx, mutation) => {
if (mutation.patch) {
return tx.patch(mutation.id, mutation.patch);
}
if (mutation.delete) {
return tx.delete(mutation.delete);
}
if (mutation.create) {
return tx.createIfNotExists(mutation.create);
}
}, client.transaction());
};
const migrateNextBatch = async () => {
const documents = await fetchDocuments();
if (documents.length === 0) {
console.log("No more documents to migrate!");
return null;
}
const mutations = buildMutations(documents);
const transaction = createTransaction(mutations);
await transaction.commit();
return migrateNextBatch();
};
migrateNextBatch().catch(err => {
console.error(JSON.stringify(err, null, 2));
process.exit(1);
});
This example shows how you can perform a migration where a document _type field is changing. It will migrate documents in batches of 10 and continue patching until no more documents are returned from the query.
A few things to note:
_type
field on a document isn't allowed. The solution to this is to create a duplicate with a new _id
and _type
, then delete the old document and patch all referencing documents with the new _id
Run this script with the command sanity exec --with-user-token migrateDocumentType.js
in a studio folder. This script deletes and changes data, so it might be wise to export your dataset first.
Knut runs developer relations at Sanity.io
How to add different types of “breaks” for Portable Text that can be translated to horizontal rules, “read more”, sections, chapters, and so on.
Go to Breaks for Portable TextAdd lists of image assets based on information in the asset document using the Structure Builder API
Go to How to list and group image asset documentsMigration script for renaming a field based on a GROQ query
Go to Rename a field across documentsUse data for the current logged in user as initial values in a new document
Go to Initial value template with current user