Mongodb обновить конкретный элемент из подмассива

У меня есть коллекция со следующей схемой:

{
  "_id" : 28,
  "n" : [{
      "a" : ObjectId("4ef8466e46b3b8140e000000"),
      "c" : 28,
      "p" : [ObjectId("4f00640646b3b88005000003"), ObjectId("4f00640146b3b88005000002"), ObjectId("4f00637d46b3b8cc0e000001"), ObjectId("4f00638046b3b8cc0e000002"), ObjectId("4f00638246b3b8cc0e000003"), ObjectId("4f00631646b3b85002000001"), ObjectId("4f00631846b3b85002000002")],
      "u" : 26
    }, {
      "a" : ObjectId("4ef8466e46b3b8140e000000"),
      "c" : 10,
      "p" : [ObjectId("4f00640146b3b88005000002"), ObjectId("4f0063fd46b3b88005000001")],
      "u" : 26
    }, {
      "a" : ObjectId("4ef8467846b3b8780d000001"),
      "u" : 26,
      "p" : [ObjectId("4f00637b46b3b8cc0e000000")],
      "c" : 28
    }, {
      "a" : ObjectId("4ef85a3e46b3b84408000000"),
      "u" : 26,
      "p" : [ObjectId("4f00631046b3b85002000000")],
      "c" : 28
    }]
}

Мне нужно обновить один из элементов в массиве в документе с _id = 28 но только если a = некоторому значению и c = некоторому значению

db.coll.update({
'_id' : 28,
'n.a' : new ObjectId('4ef85a3e46b3b84408000000'),
'n.c' : 28
},
{
  $push : {
     'n.$.p' : ObjectId("4b97e62bf1d8c7152c9ccb74")
  },
  $set : {
     'n.$.t' : ISODate("2013-05-13T14:22:46.777Z")
  }
})

Итак, я хочу обновить конкретный элемент из массива: и, насколько можно видеть, это четвертый элемент. Проблема в том, что при выполнении запроса он, скорее всего, обновляет первый элемент.

Как я могу это исправить?

12 голосов | спросил Salvador Dali 12 FebruaryEurope/MoscowbSun, 12 Feb 2012 10:45:53 +0400000000amSun, 12 Feb 2012 10:45:53 +040012 2012, 10:45:53

1 ответ


0

Проблема в вашем коде: dot-notation, так как при указании точечного обозначения вы предполагаете, что указанные критерии фильтра должны соответствовать одному массиву элемент, который удовлетворяет всем критериям. Но это не так. Точечная запись на массивах может захватывать любой элемент массива, если соответствует какой-либо один критерий. Вот почему вы получаете неожиданное обновление.

Вы должны использовать $elemMatch , чтобы сопоставить все фильтры в элементе array.

db.coll.update({
'_id' : 28,
n: { 
   $elemMatch:{
       a : new ObjectId('4ef85a3e46b3b84408000000'),
       c : 28 }
   }
},
{
  $push : {
     'n.$.p' : ObjectId("4b97e62bf1d8c7152c9ccb74")
  },
  $set : {
     'n.$.t' : ISODate("2013-05-13T14:22:46.777Z")
  }
})

и вывод

    {
        "a" : ObjectId("4ef85a3e46b3b84408000000"),
        "c" : 28,
        "p" : [
            ObjectId("4f00631046b3b85002000000"),
            ObjectId("4b97e62bf1d8c7152c9ccb74")
        ],
        "t" : ISODate("2013-05-13T14:22:46.777Z"),
        "u" : 26
    }
ответил RameshVel 12 FebruaryEurope/MoscowbSun, 12 Feb 2012 11:27:39 +0400000000amSun, 12 Feb 2012 11:27:39 +040012 2012, 11:27:39

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132