2012-05-22 2 views
7

У меня есть объектная структура, как это: Изменение последнего элемента массива

{ 
    name: "...", 
    pockets: [ 
     { 
      cdate: "....", 
      items: [...] 
     } 
     ... 
    ] 
} 

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

  • pockets.-1.items
  • pockets.$last.items

Можно ли изменить последний элемент? Если да, то как?

+0

Я исправлю, что вы хотите изменить 'items', а не получить его? – paulmelnikow

+0

Да, вы правы. В выборке я могу использовать оператор $ slice. – Muatik

+0

Я уверен, что это не может быть сделано простым обновлением, если у вас нет другого способа сопоставить последний карман. – paulmelnikow

ответ

2

Я не знаю, как это сделать, используя однострочный запрос. Но вы можете выбрать запись, обновить и сохранить ее.

var query = <insert query here>; 
var mydocs = db.mycollection.find(query); 
for (var i=0 ; i<mydocs.length ; i++) { 
    mydocs[i].pockets[pockets.length-1].items.push('new item'); 
    db.mycollection.save(mydoc); 
} 
+3

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

+0

@ АсяКамский отличная точка ... Я обновлю свой ответ. – McGarnagle

2

Я не верю, что это возможно сделать атомарно. Существует request для этой функции, которая будет добавлена ​​в MongoDB.

Если вы можете гарантировать безопасность потоков в коде приложения , вы могли бы использовать последовательность $ выскочить из карманов массива (который удаляет последний элемент из карманов) к переменному р, а затем $ addToSet в p.items , теперь вы можете $ push p вернуться в карманы. Но если ваше приложение не имеет возможности гарантировать, что только один процесс может сделать это за один раз, другой процесс может изменить массив в середине этих шагов, и вы можете потерять это обновление.

Вы также можете ознакомиться с семантикой «Обновить, если текущая» here, чтобы увидеть другой способ, с помощью которого можно обойти возможную гонку по нескольким темам.

Смежные вопросы