尝试使用 Mongoose 进行批量更新插入。最干净的方法是什么?

2024-06-02

我有一个集合,其中包含包含三个字段的文档:名字、姓氏和年龄。我试图找出 Mongoose 中的哪个查询可以用来进行批量更新插入。我的应用程序偶尔会收到具有相同三个字段的新对象数组。我希望查询检查文档中是否已存在名字和姓氏,如果存在,则更新年龄(如果不同)。否则,如果名字和姓氏不存在,则插入新文档。

目前,我只进行导入 - 尚未构建此更新插入片段的逻辑。

app.post('/users/import', function(req, res) {
  let data = req.body;
  let dataArray = [];
  data.forEach(datum => {
    dataArray.push({
        first: datum.first,
        last: datum.last,
        age: datum.age
    })
})

User.insertMany(dataArray, answer => {
    console.log(`Data Inserted:`,answer)
})

`

我的用户模型如下所示:

const mongoose = require('mongoose');

const Schema = mongoose.Schema;

const userSchema = new Schema({
  first: String,
  last: String,
  age: Number,
  created_at: { type: Date, default: Date.now }
});

var User = mongoose.model('User', userSchema);
module.exports = User;

([电子邮件受保护] /cdn-cgi/l/email-protection, [电子邮件受保护] /cdn-cgi/l/email-protection)

TL;DR

await GasStation.collection.bulkWrite([ // <<==== use the model name
  {
    'updateOne': {
      'filter': { 'id': '<some id>' },
      'update': { '$set': { /* properties to update */ } },
      'upsert': true,  // <<==== upsert in every document
    }
  },
  /* other operations here... */
]);

很长的故事:

经过一番挣扎后Mongoose API 文档贫乏 http://mongoosejs.com/docs/api.html#model_Model.bulkWrite,我解决了批量更新插入调整updateOne:{}操作在bulkWrite() method.

需要考虑一些未记录的事情:

// suppose:
var GasStation = mongoose.model('gasstation', gasStationsSchema);
var bulkOps = [ ];

// for ( ... each gasStation to upsert ...) {
  let gasStation = { country:'a', localId:'b', xyz:'c' };
  // [populate gasStation as needed]
  // Each document should look like this: (note the 'upsert': true)
  let upsertDoc = {
    'updateOne': {
      'filter': { 'country': gasStation.country, 'localId': gasStation.localId },
      'update': gasStation,
      'upsert': true
  }};
  bulkOps.push(upsertDoc);
// end for loop

// now bulkWrite (note the use of 'Model.collection')
GasStation.collection.bulkWrite(bulkOps)
  .then( bulkWriteOpResult => {
    console.log('BULK update OK');
    console.log(JSON.stringify(bulkWriteOpResult, null, 2));
  })
  .catch( err => {
    console.log('BULK update error');
    console.log(JSON.stringify(err, null, 2));
  });

这里的两个关键问题是 API 文档不完整的问题(至少在撰写本文时):

  • 'upsert': true 在每个文档中。 Mongoose API () 中没有对此进行记录,通常指的是节点 mongodb-native司机。看着更新此驱动程序中的一个 http://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#updateOne,你可以考虑添加'options':{'upsert': true},但是,不……那不行。我还尝试将这两种情况添加到bulkWrite(,[options],)争论,也没有效果。
  • GasStation.collection.bulkWrite()。虽然猫鼬的bulkWrite()方法 http://mongoosejs.com/docs/api.html#model_Model.bulkWrite声称它应该被称为Model.bulkWrite()(在这种情况下,GasStation.bulkWrite()),这将触发MongoError: Unknown modifier: $__. So, Model.collection.bulkWrite()必须使用。

另外,请注意:

  • You don't need to use the $set mongo operator in the updateOne.update field, since mongoose handles it in case of upsert (see bulkWrite() comments in example http://mongoosejs.com/docs/api.html#model_Model.bulkWrite).
  • 请注意,我在架构中的唯一索引(更新插入正常工作所需)定义为:

gasStationsSchema.index({ country: 1, localId: 1 }, { unique: true });

希望能帮助到你。

==> 编辑:(猫鼬 5?)

正如@JustinSmith 所注意到的,$setMongoose 添加的运算符似乎不再工作了。也许是因为 Mongoose 5?

无论如何,使用$set明确应该这样做:

'update': { '$set': gasStation },
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

尝试使用 Mongoose 进行批量更新插入。最干净的方法是什么? 的相关文章

随机推荐