Mongoose updateMany with aggregation pipeline

Viewed 1382

MongoDB supports updates with aggregation pipelines (https://docs.mongodb.com/manual/tutorial/update-documents-with-aggregation-pipeline/). Here is sample query(https://mongoplayground.net/p/i7A4YoIhyS5). The update function takes an array (the pipeline) as the second argument.

In Mongoose however, it turns out you can pass only an object (by the docs https://mongoosejs.com/docs/api.html#model_Model.updateMany, also I have tried myself and array is not supported). Are there any ways to use Updates with aggregation pipelines in Mongoose?

1 Answers

Mongoose has not implemented a convenience wrapper for that just yet.

However, Model.collection provides read-only access to the underlying collection object from the native driver, including its methods.

Instead of Model.updateMany(), try using Model.collection.updateMany(), which should use the syntax described for the MongoDB Node.JS driver

Edit

Ugly demo code using Mongoose 5.12 and MongoDB 4.2:

const mongoose=require('mongoose');

const testSchema = new mongoose.Schema({ test:String });

const testModel = mongoose.model('testModel',testSchema);

mongoose.connect('mongodb://localhost/test', {useNewUrlParser: true, useUnifiedTopology: true});

async function main() {
    const doc = new testModel({test:"testString"});
    await doc.save();
    const result = await testModel.collection.updateMany({},[{$set:{updated:{$concat:["$test",{$toString:"$_id"}]}}}]);
    console.log("matchedCount:",result.matchedCount);
    console.log("modifiedCount:",result.modifiedCount);
    const newdoc = await testModel.findOne({});
    console.log(newdoc);
    process.exit();
}

main();

Output from the above:

matchedCount: 1
modifiedCount: 1
{
  _id: 606945d4d5a5d9bec9038a59,
  test: 'testString',
  __v: 0,
  updated: 'testString606945d4d5a5d9bec9038a59'
}
Related