Подтвердить что ты не робот

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")
  }
})

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

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

4b9b3361

Ответ 1

Проблема в вашем коде 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
    }