有条件地删除嵌套在MongoDB文档数组中的Subdocument

时间:2015-07-10 08:22:50

标签: arrays mongodb mongodb-query

我有一个包含这样的文档的集合:

{
    "_id" : "ABC",
    "Name" : "Rajesh",
    "createstmp" : ISODate("2015-06-22T17:09:16.705Z"),
    "updstmp" : ISODate("2015-06-22T19:31:53.527Z"),
    "AvgValue" : "65",
    "PreValues" : [ 
        {
            "Date" : 20150709,
            "Rate" : [ 
                {
                    "Time" : 1566,
                    "value" : 60
                }, 
                {
                    "Time" : 1500,
                    "value" : 400
                }, 
                {
                    "Time" : 1400,
                    "value" : 100
                }, 
                {
                    "Time" : 1500,
                    "value" : 103
                }
            ]
        }
    ]
}

我想删除特定日期值的重复文档 例如,如果时间值为1500,我需要拉出文档并在单个批量操作中将其推送给(值)新值。

这是我的查询

bulk.find({ "_id":"ABC" })
    .update(
        { 
            "_id": "ABC",
            "PreValues": { "Date": 20150709 }
        },
       { 
           $pu‌​ll: { "PreValues": { "Rate": { "Time": 1000 } } }
       }
    ); 
bulk.find({ "_id":"ABC" })
    .update(
        { "_id": "ABC","PreValues": { "Date": 20150709 }},
        { $pu‌​sh : { 
            "PreValues": { "Rate": { "Time": 1000,"Rating": 100 }}
        }}
    ); 
bulk.execute();

1 个答案:

答案 0 :(得分:0)

拥有嵌套数组并不是一个好主意,因为你能够以原子方式做的唯一事情是$push$pull。有关“嵌套数组”在这里不合适的原因的详细信息,请参阅positional $ operator,但基本上您只能匹配“外部”数组元素的位置。

这基本上就是你在这里所缺少的,当然还有用于访问元素的正确的“点符号”:

var bulk = db.ABA.initializeOrderedBulkOp();
bulk.find({ "_id": "ABC", "PreValues.Date": 20150709 })
    .updateOne({ "$pull": { "PreValues.$.Rate": { "Time": 1500 } } })
bulk.find({ "_id": "ABC", "PreValues.Date": 20150709 })
    .updateOne({ "$push": { "PreValues.$.Rate": { "Time": 1500, "Rating": 100 } } })
bulk.execute();

这样就改变了文档:

{
    "_id" : "ABC",
    "Name" : "Rajesh",
    "createstmp" : ISODate("2015-06-22T17:09:16.705Z"),
    "updstmp" : ISODate("2015-06-22T19:31:53.527Z"),
    "AvgValue" : "65",
    "PreValues" : [
            {
                    "Date" : 20150709,
                    "Rate" : [
                            {
                                    "Time" : 1566,
                                    "value" : 60
                            },
                            {
                                    "Time" : 1400,
                                    "value" : 100
                            },
                            {
                                    "Time" : 1500,
                                    "Rating" : 100
                            }
                    ]
            }
    ]
}

这是两个语句的正确语法,只需一个响应就可以同时向服务器发送请求。

请注意,您需要在.find()中查询外部数组中的字段以进行匹配。这样就可以使用该元素的匹配索引填充positional $ operator,并且运算符知道要对哪个数组元素进行操作。