如何在数组嵌套数组中更新多个文档? (MongoDB 3.6)

时间:2018-11-07 06:41:23

标签: mongodb

我正在尝试更新多个深度嵌套数组中的所有customerId道具:

// Collection before update
[{
  cycle: [
    [[{customerId: "1"}], [], [], [{customerId: "1"}], [], [], []],
    [[], [], [], [], [], [], []],
    [[], [], [], [], [], [], []],
    [[], [{customerId: "1"}], [], [], [], [], []],
  ]
}]

// Collection after update
[{
  cycle: [
    [[{customerId: "2"}], [], [], [{customerId: "2"}], [], [], []],
    [[], [], [], [], [], [], []],
    [[], [], [], [], [], [], []],
    [[], [{customerId: "2"}], [], [], [], [], []],
  ]
}]

我正在运行MongoDB 3.6。我尝试了$$[]$[<identifier>]arrayFilters的各种组合:

db.arrayTest.update({},     
  { "$set": { "cycle.$[].$[day].customerId": "2"}},     
  { arrayFilters: [{"day.customerId": "1"}] }   )
// WriteResult({
//  "nMatched" : 0,
//  "nUpserted" : 0,
//  "nModified" : 0,
//  "writeError" : {
//    "code" : 28,
//    "errmsg" : "Cannot create field 'customerId' in element {0: [ { customerId: \"1\" } ]}"
//  }
// })

db.arrayTest.update(
  {"cycle.$[].$[].customerId": "1"},     
  { "$set": { "cycle.$[].$[].customerId": "2"}}
)
// WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0 })

db.arrayTest.update(
  {"cycle.$.$.customerId": "1"},     
  { "$set": { "cycle.$.$.customerId": "2"}}
)
// WriteResult({
//  "nMatched" : 0,
//  "nUpserted" : 0,
//  "nModified" : 0,
//  "writeError" : {
//    "code" : 2,
//    "errmsg" : "Too many positional (i.e. '$') elements found in path 'cycle.$.$.customerId'"
//  }
// })

我也尝试了各种查询,但都没有成功:

db.arrayTest.find({"cycle.$.$.customerId": "1"})
// ""

db.arrayTest.find({"cycle.$[].$[].customerId": "1"})
// ""

// The following works but requires using explicit array indices
db.arrayTest.find({"cycle.0.0.customerId": "1"})
// { "_id": ObjectId("5bdbeae940eedc517cafb84f"), "cycle": [
//     [
//       [{ "customerId": "1" }],
//       [],
//       [],
//       [{ "customerId": "1" }],
//       [],
//       [],
//       []
//     ],
//     [
//       [],
//       [],
//       [],
//       [],
//       [],
//       [],
//       []
//     ],
//     [
//       [],
//       [],
//       [],
//       [],
//       [],
//       [],
//       []
//     ],
//     [
//       [],
//       [{ "customerId": "1" }],
//       [],
//       [],
//       [],
//       [],
//       []
//     ]
//   ] }

以下查询有效:

db.arrayTest.find({"cycle": {$elemMatch: { $elemMatch: { $elemMatch: { "customerId": "1"}}}}})

1 个答案:

答案 0 :(得分:0)

对于MongoDB 3.6 +,arrayFilters为此很好地工作。 MongoDB 3.6版本还添加了$[]$[<identifier>] multi-element array update operators。例如:

db.arrayTest.insertMany([{
  array: [
    [[{id: "1"}], [{id: "2"}], [], [{id: "1"}], []]
  ]
}])


db.arrayTest.update({},
    { $set: { "array.$[].$[].$[el].id": "updated" } },
    { arrayFilters: [{"el.id": "1"}], multi: true}    
)

db.arrayTest.find({})
// [{
//   array: [
//     [[{id: "updated"}], [{id: "2"], [], [{id: "updated"}], []]
//   ]
// }]