根据其他属性推送到数组

时间:2019-06-29 21:03:26

标签: arrays mongodb push

对象结构(仅作为示例,一个对象中有数千个回调):

{
    "_id" : ObjectId("5ce82dd1eed5a17f33ec025a"),
    "id" : "AAA",
    "pac" : "",
    "callbacks" : [ 
        {
            "_id" : ObjectId("5ce82e29eed5a17f33ec0287"),
            "timestamp" : 1558720040,
            "type" : "data_bidir",
            "seqNumber" : 49,
            "messages" : [ 
                {
                    "isCode" : true,
                    "_id" : ObjectId("5ce82e29eed5a17f33ec0294"),
                    "key" : "action",
                    "value" : "extra_long_press"
                }, 
                {
                    "isCode" : false,
                    "_id" : ObjectId("5ce82e29eed5a17f33ec0293"),
                    "key" : "version",
                    "value" : "6"
                }, 
                {
                    "isCode" : false,
                    "_id" : ObjectId("5ce82e29eed5a17f33ec0292"),
                    "key" : "firmware",
                    "value" : "0.45"
                }
            ],
            "created" : ISODate("2019-05-24T17:47:21.476Z")
        }, 
        {
            "_id" : ObjectId("5ce82e42eed5a17f33ec0295"),
            "timestamp" : 1558720040,
            "type" : "service_geoloc",
            "seqNumber" : 49,
            "messages" : [ 
                {
                    "isCode" : true,
                    "_id" : ObjectId("5ce82e42eed5a17f33ec029b"),
                    "key" : "lqi",
                    "value" : "Good"
                }, 
                {
                    "isCode" : false,
                    "_id" : ObjectId("5ce82e42eed5a17f33ec029a"),
                    "key" : "latitude",
                    "value" : "50.67593721530616"
                }, 
                {
                    "isCode" : false,
                    "_id" : ObjectId("5ce82e42eed5a17f33ec0299"),
                    "key" : "longitude",
                    "value" : "14.03118116624828"
                }, 
                {
                    "isCode" : false,
                    "_id" : ObjectId("5ce82e42eed5a17f33ec0298"),
                    "key" : "radius",
                    "value" : "8514"
                }, 
                {
                    "isCode" : true,
                    "_id" : ObjectId("5ce82e42eed5a17f33ec0297"),
                    "key" : "da_source",
                    "value" : "2"
                }, 
                {
                    "isCode" : true,
                    "_id" : ObjectId("5ce82e42eed5a17f33ec0296"),
                    "key" : "da_status",
                    "value" : "1"
                }
            ],
            "created" : ISODate("2019-05-24T17:47:46.547Z")
        }
    ]
}

仅当a)callbacks.type为“ service_geoloc”和b)如果消息包含key = da_source和value = 2(在示例数据中,第二个回调将受到影响)时,我才需要将对象推送到所有消息。

条件a)可以通过arrayFilters轻松管理:

db.getCollection("devices").updateMany(
  { id: 'AAA'},
  { $push: { 
    "callbacks.$[c].messages" : { 
        $each: [{key: "action", value: "atlas_position_network", isCode: true}],
        $position: 0
        }
    }     
  },
  { arrayFilters: [{"c.type": "service_geoloc"}], multi: true}
)

但是我不知道如何应用条件b)。我还尝试了elemMatch-它在两种情况下均可工作,但仅更新了一条消息。

1 个答案:

答案 0 :(得分:0)

我能够分两步完成。也许使用shell一步不可能做到这一点。

步骤1 =将项目推入具有常规值的message数组中

db.getCollection("devices").updateMany(
  { id: 'AAA'},
  { $push: { 
    "callbacks.$[c].messages" : { 
        $each: [{key: "action", value: "atlas_position_network", isCode: true}],
        $position: 0
        }
    }     
  },
  { arrayFilters: [{"c.type": "service_geoloc"}], multi: true}
)

步骤2 =根据固定位置上的其他项目更新值:

db.getCollection('devices').updateMany(
    { id: 'AAA' },
    { $set: { "callbacks.$[c].messages.0.value": "atlas_position_wifi"} },
    { arrayFilters: [{ "c.type": "service_geoloc", "c.messages.5.value": "6",  "c.messages.5.key": "da_source" }], multi: true }
)