вставить в определенный индекс для массива монго - PullRequest
11 голосов
/ 20 июня 2011

Mongo поддерживает массивы документов внутри документов.Например, что-то вроде

{_id: 10, "coll": [1, 2, 3] }

Теперь представьте, что я хотел вставить произвольное значение с произвольным индексом

{_id: 10, "coll": [1, {name: 'new val'}, 2, 3] }

Я знаю, что вы можете обновить значения на месте с помощью $ и $ set, но ничего для вставки.Это отстойно, что нужно заменить весь массив только для вставки по определенному индексу.

Ответы [ 5 ]

16 голосов
/ 26 октября 2013

Начиная с версии 2.6 , вы наконец можете это сделать. Вы должны использовать оператор $ position . Для вашего конкретного примера:

db.students.update(
  { _id: 10},
  { $push: {
     coll: {
       $each: [ {name: 'new val'} ],
       $position: 1
     }
  }}
)
1 голос
/ 25 марта 2014

Удобный ответ (не выбранный ответ, но самый высокий рейтинг) из этого аналогичного поста: Можете ли вы использовать mongo $ push prepend вместо append?

использует $ для вставки 3 напервая позиция в массиве, называемая «массив».Пример из соответствующего ответа Сергея Никитина:

db.test.update({"_id" : ObjectId("513ad0f8afdfe1e6736e49eb")}, 
                 {'$set': {'array.-1':     3}})
1 голос
/ 30 марта 2012

Следующие действия помогут:

var insertPosition = 1;
var newItem = {name: 'new val'};

db.myCollection.find({_id: 10}).forEach(function(item)
{
    item.coll = item.coll.slice(0, insertPosition).concat(newItem, item.coll.slice(insertPosition));
    db.myCollection.save(item);
});

Если insertPosition является переменной (то есть вы точно не знаете, куда хотите ее вставить, но знаете, что хотите вставить еепосле элемента с name = "foo" просто добавьте цикл for() перед назначением item.coll =, чтобы найти insertPosition (и добавьте 1 к нему, поскольку вы хотите вставить его ПОСЛЕ name = "foo".

0 голосов
/ 30 декабря 2013

С помощью оператора $ position это можно сделать начиная с версии 2.5.3.

Он должен использоваться с оператором $ each. С документация :

db.collection.update( <query>,
                  { $push: {
                              <field>: {
                                         $each: [ <value1>, <value2>, ... ],
                                         $position: <num>
                              }
                           }
                  }
                )
0 голосов
/ 21 июня 2011

По поводу вашего комментария:

Хорошо .. с одновременными пользователями это будет проблематично для любой базы данных ...

Я бы сделал следующее: Добавьте последнюю измененную метку времени в документ. Загрузите документ, дайте пользователю изменить его и используйте отметку времени в качестве фильтра при обновлении документа, а также обновите отметку времени за один шаг. Если он обновляет 0 документов, вы знаете, что он был изменен за это время, и вы можете попросить пользователя перезагрузить его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...