В MongoDB, как удалить элемент массива по его индексу
{
"_id" : ObjectId("4d1cb5de451600000000497a"),
"name" : "dannie",
"interests" : [
"guitar",
"programming",
"gadgets",
"reading"
]
}
в приведенном выше примере Предположим, что приведенный выше документ находится в db.люди!--4--> коллекция. Как удалить 3-й элемент интересы массив-это индекс?
Edit:
Это мое текущее решение:
var interests = db.people.findOne({"name":"dannie"}).interests;
interests.splice(2,1)
db.people.update({"name":"dannie"}, {"$set" : {"interests" : interests}});
есть ли более прямой путь?
5 ответов
нет прямого способа вытягивания / удаления по индексу массива. На самом деле, это открытый вопрос http://jira.mongodb.org/browse/SERVER-1014, Вы можете голосовать за него.
обходной путь использует $unset, а затем $pull:
db.lists.update({}, {$unset : {"interests.3" : 1 }})
db.lists.update({}, {$pull : {"interests" : null}})
Update: как упоминалось в некоторых комментариях, этот подход не является атомарным и может вызвать некоторые условия гонки, если другие клиенты читают и/или пишут между двумя операциями. Если нам нужна атомная операция, мы мог бы:
- читать документ из базы данных
- обновите документ и удалите элемент в массиве
- заменить документ в базе данных. Чтобы убедиться, что документ не изменился с момента его чтения, мы можем использовать обновление, если текущий шаблон описан в документах монго
можно использовать $pull
модификатор update
операция удаления определенного элемента в массиве. В случае, если вы предоставили запрос будет выглядеть так:
db.people.update({"name":"dannie"}, {'$pull': {"interests": "guitar"}})
кроме того, вы можете использовать $pullAll
для удаления всех вхождений. Подробнее об этом на странице официальной документации -http://www.mongodb.org/display/DOCS/Updating#Updating-%24pull
это не использует индекс в качестве критерия для удаления элемента, но все же может помочь в случаях подобный вашему. IMO, использование индексов для адресации элементов внутри массива не очень надежно, так как mongodb не согласуется с порядком элементов, как я знаю.
Я бы рекомендовал использовать поле GUID (я обычно использую ObjectID) или поле автоматического увеличения для каждого поддокумента в массиве.
с этим GUID легко выдать $ pull и быть уверенным, что правильный будет вытащен. То же самое касается и других операций массива.
вместо того, чтобы использовать unset (как в принятом ответе), я решаю это, устанавливая поле в уникальное значение (т. е. не NULL), а затем немедленно вытаскивая это значение. Немного безопаснее с асинхронной точки зрения. Вот код:
var update = {};
var key = "ToBePulled_"+ new Date().toString();
update['feedback.'+index] = key;
Venues.update(venueId, {$set: update});
return Venues.update(venueId, {$pull: {feedback: key}});
надеюсь, монго рассмотрит это, возможно, путем расширения модификатора $position для поддержки $pull, а также $push.
вместо использования $pull мы можем использовать $pop для удаления элементов в массиве по его индексу. Но вы должны вычесть 1 из позиции индекса для удаления на основе индекса.
для E. g Если вы хотите удалить элемент в индексе 0, вы должны использовать -1, для индекса 1 вы должны использовать 0 и так далее...
запрос на удаление 3-го элемента (гаджетов):
db.people.update({"name":"dannie"}, {'$pop': {"interests": 1}})
для справки: https://docs.mongodb.com/manual/reference/operator/update/pop/