为了账号安全,请及时绑定邮箱和手机立即绑定

MongoDB 在数组中插入

MongoDB 在数组中插入

GCT1015 2022-01-07 19:29:59
我正在尝试在 mongoDB 数组中插入、更新、删除值。我的 mongoDB 版本是3.4.23。这是我的收藏:{  "link": "abc.com",  "Values": [{      "valueID": "v1",      "date": "05-07-2015",      "value": "10"  }]}我正在尝试进行一些upsert类型的查询来插入/更新Values数组数据,但无法这样做。我得到了这个解决方案,但它对我不起作用。可以说我有 "valueID": "v1"{    "valueID": "v1",    "date": "05-07-2015",    "value": "20"}所以在这种情况下,我想"value": "20"在上面的集合中设置,所以输出应该是:{  "link": "abc.com",  "Values": [{      "valueID": "v1",      "date": "05-07-2015",      "value": "20"//updated value  }]}如果我通过了,"valueID": "v2"那么它应该像这样将新值插入到集合中:{  "link": "abc.com",  "Values": [{      "valueID": "v1",      "date": "05-07-2015",      "value": "10"  },  {    "valueID": "v2",    "date": "xyz",    "value": "xyz"  }]}您的帮助将不胜感激。
查看完整描述

3 回答

?
皈依舞

TA贡献1851条经验 获得超3个赞

不幸的是,这不能在使用 anupsert或类似的单个更新语句中完成。


这可以使用从MongoDB 3.2开始支持的bulkWrite()来实现。


您还可以使用MongoDB 4.2 中的新update()命令 - 请注意,这仅在 4.2 中可用。


update 命令现在允许多个更新语句。虽然您可能必须运行两个更新命令,但您只需要发送一次命令并让 MongoDB 为您批处理语句。


鉴于您的要求,您可以尝试以下操作,首先尝试使用$ 位置运算符更新数组中的相关元素。


然后我们使用$addToSet数组运算符,它将尝试添加一个新的数组元素 - 只有在没有找到适合我们的场景的匹配数组元素时,在步骤 1 中无法进行更新。


这两种解决方案都适用于您的场景。


使用 bulkWrite()


db.getCollection("tests").bulkWrite([

    {

        updateOne: {

            filter: {link: "abc.com", "Values.valueID": "v2"},

            update: {$set: {"Values.$.value": "xyz"}}

        }

    },

    {

        updateOne: {

            filter: {link: "abc.com"},

            update: {

                $addToSet: {

                    "Values": {

                        "valueID": "v2",

                        "date": "05-07-2015",

                        "value": "xyz"

                    }

                }

            }

        }

    }

]);

使用新的 update() 命令:


db.runCommand(

            {

                update: "tests",

                updates: [

                    {

                        q: {link: "abc.com", "Values.valueID": "v2"},

                        u: {$set: {"Values.$.value": "xyz"}}

                    },

                    {

                        q: {link: "abc.com"},

                        u: {

                            $addToSet: {

                                "Values": {

                                    "valueID": "v2",

                                    "date": "05-07-2015",

                                    "value": "xyz"

                                }

                            }

                        }

                    }

                ],

                ordered: false,

                writeConcern: {w: "majority", wtimeout: 5000}

            }

        )

样本数据:


db.getCollection("tests").insertMany([{

        "link": "abc.com",

        "Values": [

            {

                "valueID": "v1",

                "date": "05-07-2015",

                "value": "10"

            }

        ]

    },

    {

        "link": "def.com",

        "Values": [

            {

                "valueID": "v1",

                "date": "05-07-2015",

                "value": "1"

            }

        ]

    }]

);

不存在时插入数组:


db.runCommand(

            {

                update: "tests",

                updates: [

                    {

                        q: {link: "abc.com", "Values.valueID": "v2"},

                        u: {$set: {"Values.$.value": "xyz"}}

                    },

                    {

                        q: {link: "abc.com"},

                        u: {

                            $addToSet: {

                                "Values": {

                                    "valueID": "v2",

                                    "date": "05-07-2015",

                                    "value": "xyz"

                                }

                            }

                        }

                    }

                ],

                ordered: false,

                writeConcern: {w: "majority", wtimeout: 5000}

            }

        )

结果:


    { 

        "_id" : ObjectId("5dd8164969f4361ce9821b88"), 

        "link" : "abc.com", 

        "Values" : [

            {

                "valueID" : "v1", 

                "date" : "05-07-2015", 

                "value" : "20"

            }, 

            {

                "valueID" : "v2", 

                "date" : "05-07-2015", 

                "value" : "xyz"

            }

        ]

    }    

更新现有值:


db.runCommand(

            {

                update: "tests",

                updates: [

                    {

                        q: {link: "abc.com", "Values.valueID": "v2"},

                        u: {$set: {"Values.$.value": "new value"}}

                    },

                    {

                        q: {link: "abc.com"},

                        u: {

                            $addToSet: {

                                "Values": {

                                    "valueID": "v2",

                                    "date": "05-07-2015",

                                    "value": "new value"

                                }

                            }

                        }

                    }

                ],

                ordered: false,

                writeConcern: {w: "majority", wtimeout: 5000}

            }

        )

结果:


    "_id" : ObjectId("5dd8164969f4361ce9821b88"), 

    "link" : "abc.com", 

    "Values" : [

        {

            "valueID" : "v1", 

            "date" : "05-07-2015", 

            "value" : "20"

        }, 

        {

            "valueID" : "v2", 

            "date" : "05-07-2015", 

            "value" : "new value"

        }

    ]

}


查看完整回答
反对 回复 2022-01-07
?
江户川乱折腾

TA贡献1851条经验 获得超5个赞

MongoDB 4.2


使用聚合管道更新

从 MongoDB 4.2开始,db.collection.update()方法可以接受指定要执行的修改的聚合管道[ stage1, stage2, ... ]。


所以这里$reduce有一些$condition 的运算符可以解决问题。


db.getCollection("ashish2").update(

  //filter criteria for the update operation

  { },

  [{ "$set": {

    "Values": {

      "$reduce": {

        "input": "$Values",

        "initialValue": [],

        "in": {

          "$concatArrays": [

            "$$value",

            {

              "$cond": [

                // Here you can select your value with which you want to match

                { "$eq": ["$$this.valueID", "v2"] },

                // Updation after match

                [{ "valueID": "v1", "date": "05-07-2015", "value": "20" }], 

                // Updation when doesn't match

                {

                  "$concatArrays": [

                    [{ "valueID": "v1", "date": "05-07-2015", "value": "20" }],

                    ["$$this"]

                  ]

                }

              ]

            }

          ]

        }

      }

    }

  }}]

)


查看完整回答
反对 回复 2022-01-07
?
侃侃尔雅

TA贡献1801条经验 获得超15个赞

看看 $addToSet 运算符

$addToSet 运算符向数组添加一个值,除非该值已经存在,在这种情况下 $addToSet 对该数组不做任何事情。

https://docs.mongodb.com/manual/reference/operator/update/addToSet/index.html


查看完整回答
反对 回复 2022-01-07
  • 3 回答
  • 0 关注
  • 391 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信