【问题标题】:Node.js Mongoose .update with ArrayFiltersNode.js Mongoose .update 与 ArrayFilters
【发布时间】:2018-06-21 06:16:00
【问题描述】:

就目前而言,我可以使用 Mongo shell 使该功能正常工作,但使用 Mongoose 在 Node.js 内的嵌套数组存在问题。

成功的Mongo shell命令:

db.test.update({}, {$set: {"this.$[i].that.$[x].amnt": 10000}}, {arrayFilters: [{"i._id": ObjectId('5a568059bc44142a9ca33d09')}, {"x.userId": ObjectId('5a466acb864c752f8c9890c6')}]})

结果:将 amnt 字段更改为 10000。在对从数据库中提取的给定字符串调用 ObjectId('') 之前,没有返回匹配项。

Node.js 代码:

var conditions = {}
var update = {$set: {"this.$[i].that.$[x].amnt": 1000}
var options = {arrayFilters: [{"i._id": weekId}, {"x.userId":  r.userId}]}

myModel.update(conditions, update, options, function(err, rowsAffected){
    // handler 
}

结果:{ ok: 0, n: 0, nModified: 0 }

_id 和 userId 是模型架构中的 schema.Types.ObjectId。

我尝试使用 3.6.1 的最新文件更新 node_modules/mongodb。看来猫鼬使用3.0.1。打印到控制台 typeof(weekId) 或 typeof(r.userId) 显示字符串类型。我相信这会根据架构进行更改,但无论哪种方式,我都尝试在这些项目上调用 mongoose.Types.ObjectId(weekId) 以查看是否解决了它,但没有运气。

MongoDB:3.6.1 猫鼬:5.0.0-rc2

【问题讨论】:

    标签: javascript node.js mongodb express mongoose


    【解决方案1】:

    我不知道 Mongoose 5.0.0 是否应该支持开箱即用的 Arrayfilters,但您可以通过使用直接在 MongoDB 上执行的 Mongoose 的命令方法来实现它,因此可以利用所有可用的功能,包括 MongoDB 上的 ArrayFilters 3.6.1

    示例:

    mongoose.connection.db.command({
      update: <YourModel>.collection.name,
      updates: [
        {
          q: { 'field1.field2._id': mongoose.Types.ObjectId(<someObjectid>) },
          u: {
            $set: { 'field1.$.field2.$[field].fieldToUpdate': "updated!" },
          },
          arrayFilters: [
            { 'field._id': mongoose.Types.ObjectId(<someObjectid>) },
          ],
        },
      ],
    })
    

    【讨论】:

    • 非常感谢@actraiser,你救了我的命!
    【解决方案2】:

    我使用 mongoose v5.0.14 进行了尝试,它在 MongoDB 3.6.3 版本上运行良好!

    这是我的 package.json...

    "dependencies": {
      "mongoose": "^5.0.14",
    }
    

    这是我使用 arrayFilters 的更新函数...

    ...
    
    // my id variable
    let id = "5ad1f4dec48d7e156034c156";
    
    // mongo condition
    let mc = {_id: id};
    
    // mongo dataset
    let ds = {'contacts.$[i].main': false};
    
    // mongo options
    let op = {                             
      arrayFilters: [
        {
          $and: [
            {'i._id': {$ne: id}},
            {'i.type': 'mobile'},
          ],
        }],
    };
    
    <<Model>>.findOneAndUpdate(mc, ds, op, (err, doc) => {
      callback(err, doc);
    });
    
    ...
    

    【讨论】:

    • 嗨@TechWisdom,我用我的部分代码编辑了我的答案,使其更具体。如果有任何问题,请告诉我。
    • 非常感谢@Biruel Rick!我也没有在 Schema 中包含该字段,这是问题的一部分。
    • Mongoose ^5.0.14 findOneAndUpdate() 对我不起作用。我不得不改用update()。
    猜你喜欢
    • 2020-11-24
    • 1970-01-01
    • 2020-10-09
    • 1970-01-01
    • 2020-06-21
    • 2020-06-08
    • 2018-12-21
    • 2015-07-03
    相关资源
    最近更新 更多