【问题标题】:how to update an object of an element in array in mongodb?如何更新MongoDB中数组中元素的对象?
【发布时间】:2020-11-07 22:23:10
【问题描述】:

这是我拥有的结构,例如,如果对象键匹配,我想更新嵌套数组元素 - 我想匹配 grnno :"10431000" 并更新该对象的其他键,例如 vehicle_no、invoice_no 等。

{
    "_id" : ObjectId("5f128b8aeb27bb63057e3887"),
    "requirements" : [ 
        {
            "grns" : [ 
                {
                    "invoice_no" : "123",
                    "vehicle_no" : "345",
                    "req_id" : "5f128c6deb27bb63057e388a",
                    "grnno" : "10431000"
        },
        {
                    "invoice_no" : "abc",
                    "vehicle_no" : "def",
                    "req_id" : "5f128c6deb27bb63057e388a",
                    "grnno" : "10431001"
        }
          ]
       }
    ]
}

我试过这个代码

 db.po_grn.update({
                "requirements.grns.grnno":"10431001"
            }, {
                $set: {
                    "requirements.$.grns": {"invoice_no":"test",vehicle_no:"5455"}
                }
            })

但这正在改变我这样的结构

 "requirements" : [ 
        {
            "grns" : {
                "invoice_no" : "test",
                 "vehicle_no":"5455"

            },
            "req_id" : ObjectId("5f128b8aeb27bb63057e3886")
        }
    ],

grns 键应该是数组,更新应该是与键“grnno”匹配的特定对象。请帮帮我。谢谢。

==编辑==

var grnno = req.body.grnno;
db.po_grn.find({
    "requirements.grns.grnno":grnno
}).toArray(function(err, po_grn) {
    console.log("po_grn",po_grn);
    if (po_grn.length > 0) {
        console.log("data.grn.grnno ", grnno);
        var query = {
             requirements: {
                $elemMatch: {
                    "grns.grnno": grnno
                }
             }
        };

        var update = {
            $set: {
                'requirements.$[].grns.$[inner].invoice_no': data.invoice_no,
                'requirements.$[].grns.$[inner].vehicle_no': data.vehicle_no,
            }
        };

        var options = {
            arrayFilters: [
                { "inner.grnno" : grnno }
            ] 
        };

        db.po_grn.update(query, update, options
        , function(er, grn) {
            console.log("grn",grn,"er",er)
                        res.send({
                            status: 1,
                            message: "Grn updated successfully"
                        });
                    }
            );
    } else {
            res.send({
                status: 0,
                message: "Grn not found "
            });
    }
})

【问题讨论】:

  • 试试这个$set: { "requirements.$[].grns.$.invoice_no":"test", "requirements.$[].grns.$.vehicle_no":"5455" }
  • @Molda 这对我来说效果不佳,它更新了第 0 个索引,而它应该更新了与键匹配的索引,似乎是第一个索引。

标签: node.js arrays mongodb mongodb-query


【解决方案1】:

结合使用$[] positional-all 运算符和array filters 来更新您的内部嵌套文档。

var query = {
     requirements: {
        $elemMatch: {
            "grns.grnno": "10431001"
        }
     }
};

var update = {
    $set: {
        'requirements.$[].grns.$[inner].invoice_no': "test",
        'requirements.$[].grns.$[inner].vehicle_no': "5455",
    }
};

var options = {
    arrayFilters: [
        { "inner.grnno" : "10431001" }
    ] 
};

db.collection.update(query, update, options);

更新-

附上NodeJS原生MongoDb驱动代码,运行良好

const { MongoClient } = require('mongodb');
const url = "mongodb://localhost:27017/";

MongoClient.connect(url, function(err, db) {
  if (err) {
    throw err;
  }

  const dbo = db.db("test");
  (async() => {
    const query = {
        requirements: {
           $elemMatch: {
               "grns.grnno": "10431001"
           }
        }
    };
   
   const update = {
       $set: {
           'requirements.$[].grns.$[inner].invoice_no': "test",
           'requirements.$[].grns.$[inner].vehicle_no': "5455",
       }
    };
   
   const options = {
       arrayFilters: [
           { "inner.grnno" : "10431001" }
       ],
       multi: true
   };

    try {
      const updateResult = await dbo.collection("collection").update(query, update, options);
    } catch (err) {
      console.error(err);
    }
    db.close();
  })(); 
});

【讨论】:

  • 谢谢,这在 robo 3T 中有效,但由于某种原因,我得到“'No array filter found for identifier \'inner\' in path \'requirements.$[].grns.$[ inner].store_grn\'' " 当我在节点中运行时出现此错误。
  • @pse 你在使用 MongoDb 3.6+ 吗?
  • 它的:db版本v4.0.17
  • @pse 你是在使用 mongoose 还是原生的 mongodb node js 驱动?
  • 我将我的 mongo 版本升级到 4.2,不知何故它对我有用
猜你喜欢
  • 1970-01-01
  • 2018-02-19
  • 2017-01-05
  • 2021-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多