如何在mongodb中更新数组中元素的对象?

时间:2020-07-18 06:24:48

标签: node.js arrays mongodb mongodb-query

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

{
    "_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键应该是数组,而update应该是与键“ 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 "
            });
    }
})

1 个答案:

答案 0 :(得分:1)

结合使用$[]所有位置运算符和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驱动程序代码,效果很好

enter image description here

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();
  })(); 
});