$merge is the final stage of an aggregation pipeline when results must be written into a collection. Unlike $out, it can insert new documents, update or replace matching documents, retain existing documents, fail on matches, or apply a custom update pipeline. section 6.1.6
Use $merge when the destination requires controlled incorporation rather than wholesale replacement:
- Write to a collection in the same or another database, including the collection being aggregated. section 6.1.6
- Create the destination collection when it does not exist, or write into sharded collections. section 6.1.6
- Run reads on replica set secondaries while sending writes to the primary. section 6.1.6
Merge filtered route results
1. Filter routes whose airplane is "CR2". 2. Group by _id while selecting airport and airline fields. 3. Merge into routes with on: "_id", merging matching documents and inserting unmatched documents.
Listing 6.5 The aggregation pipeline’s $merge state
db.routes.aggregate([
{
$match: { airplane: "CR2" }
},
{
$group: {
_id: "$_id",
src_airport: { $first: "$src_airport" },
dst_airport: { $first: "$dst_airport" },
airline_name: { $first: "$airline.name" }
}
},
{
$merge: {
into: "routes",
on: "_id",
whenMatched: "merge",
whenNotMatched: "insert"
}
}
])
This listing shows the complete aggregation command and the essential whenMatched and whenNotMatched choices. section 6.1.6
$merge also supports operational workflows beyond ordinary aggregation. Atlas Stream Processing uses it to persist windowed results in an Atlas database, while Atlas Data Federation uses it to restore archived data into the same or another cluster, database, or collection. Archive restoration requires pausing the archive, creating a unique index on the merge fields, and ensuring sufficient destination capacity; very large partitioned datasets are discouraged. section 15.6.6 section 17.4
