Description:
Replaces fields in the existing document with the fields in a given expression. The expression can either be a literal map or an expression that evaluates to a map. If a given expression does not evaluate to a map, this stage returns an error.
Syntax:
Mode: {full_replace | merge_overwrite_existing | merge_keep_existing}
replace_with(map: Expr, mode: Mode)
Mode Behaviour:
full_replace: Replaces the entire document with the result of the given expression, omitting fields that don't appear in it.merge_overwrite_existing: Merges the expression with the existing document, overwriting field values in the document with values in the expressionmerge_keep_existing: Merges the expression with the existing document, only adding field values when one does not exist in the document.
Examples:
Create a cities collection with the following documents:
Node.js
await db.collection('cities').doc('SF').set({name: 'San Francisco', population: 800000, location: {country: 'USA', state: 'California'}});
await db.collection('cities').doc('TO').set({name: 'Toronto', population: 3000000, province: 'ON', location: {country: 'Canada', province: 'Ontario'}});
await db.collection('cities').doc('NY').set({name: 'New York', location: {country: 'USA', state: 'New York'}});
await db.collection('cities').cov('AT').set({name: 'Atlantis', population: null});
Using the full_replace mode to get a mutated version of the document
Extract the nested location field, discarding all other data:
Node.js
const names = await db.pipeline() .collection("/cities") .replace_with(Field.of("location"), "full_replace") .execute();
Java
Pipeline.Snapshot names = firestore.pipeline().collection("cities").replaceWith(field("location")).execute().get();
Which produces the following documents:
{country: 'USA', state: 'California'},
{country: 'Canada', province: 'Ontario'},
{country: 'USA', state: 'New York'},
{}
Using the merge_overwrite_existing mode to set fields
Set the population field of all documents to 0, overwriting existing values:
Node.js
const censoredResults = await db.pipeline() .collection("/cities") .replace_with(map("population", 0), "merge_overwrite_existing") .execute();
Which produces the following documents:
{name: 'San Francisco', population: 0, location: {country: 'USA', state: 'California'}},
{name: 'Toronto', population: 0, province: 'ON', location: {country: 'Canada', province: 'Ontario'}},
{name: 'New York', population: 0, location: {country: 'USA', state: 'New York'}},
{name: 'Atlantis', population: 0}
Using the merge_keep_existing mode to add a default value
Setting a default value for location when it doesn't appear in a document:
Node.js
const defaultedResults = await db.pipeline() .collection("/cities") .replace_with(map("location", "unknown"), "merge_keep_existing") .execute();
Which produces the following documents:
{name: 'San Francisco', population: 800000, location: {country: 'USA', state: 'California'}},
{name: 'Toronto', province: 'ON', population: 3000000, location: {country: 'Canada', province: 'Ontario'}},
{name: 'New York', location: {country: 'USA', state: 'New York'}},
{name: 'Atlantis', population: null, location: "unknown"}