Как мне обновить / установить / удалить ключ во встроенном документе / массиве в MongoDB? - PullRequest
4 голосов
/ 13 октября 2011

Я пытаюсь сбросить все значения в документе, который встроен в массив.Допустим, у меня есть коллекция coll с массивом things, содержащая значение myval.Я хочу сбросить myval.Это выглядит так:

{ things: [{ myval: 1 }, { myval: 2 }] }

Я пробовал оба

db.coll.update({}, {$unset: {'things.myval': 1}})

и

db.coll.things.update({}, {$unset: {'myval': 1}})

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

Ответы [ 4 ]

1 голос
/ 11 апреля 2019

Я столкнулся с этим и был расстроен, увидев, что единственное, что могло сделать это - использовать вложенный forEach. Поэтому после некоторых поисков я нашел другой путь! Начиная с версии 3.6, существует позиционный оператор all ($[]) (версия 3.6 была введена таким образом после того, как был задан этот вопрос ... и даже после того, как он был активен в последний раз, НО кто-нибудь другой сталкивался с этим )

Чтобы удалить столбец myval из первого встроенного документа для сопоставления, сделайте следующее:

db.coll.update(
  {things: {'$exists': true}},
  {$unset: {'things.$[].myval': 1}}
)

или если вы хотите удалить его из всех соответствующих документов, используйте updateMany

db.coll.updateMany(
  {things: {'$exists': true}},
  {$unset: {'things.$[].myval': 1}}
)

$unset будет редактировать его только в том случае, если значение существует, но оно не будет выполнять безопасную навигацию (т. Е. Не будет проверять, существуют ли вещи в первую очередь), поэтому существует необходимость во встроенном документе / массиве.

1 голос
/ 23 апреля 2015

Должен работать с вашим первым подходом в соответствии с официальной документацией:

db.coll.update({}, {$unset: {'things.myval': 1}})

Но это не работает для меня. Итак, решение, которое я нашел, применимо к вашему примеру:

db.coll.find().forEach(function(o) {
    for(var i=0; i<o.things.length; i++) {
        var unset = {};
        unset["things." + i + ".myval"] = "";
        db.coll.update( { "_id": o._id  }, { "$unset": unset } );
    }
})

Или с более функциональным стилем:

db.coll.find().forEach(function(o) {
    o.things.forEach(function(t, i) {
        var unset = {};
        unset["things." + i + ".myval"] = "";
        db.coll.update( { "_id": o._id  }, { "$unset": unset } );
    })
})
1 голос
/ 14 октября 2011

Вы можете удалить значение из «массива», используя оператор $ pull :

db.coll.update({}, {$pull: {'things': {'myval': 1}}});

Также ознакомьтесь с документацией $ pull :

http://www.mongodb.org/display/DOCS/Updating#Updating-%24pull

0 голосов
/ 14 октября 2011

Это не может работать, потому что селектор {} -empty выбирает более одного документа, и обновление обычно пытается обновить один документ. Чтобы заставить его работать, используйте флаг multi , чтобы сообщитьМонго обновляет, что больше чем один документ приходит.

multi - указывает, что все документы, соответствующие критериям соответствия, должны быть обновлены, а не только один.Может быть полезно с операторами $ ниже.

db.coll.update({}, {$unset: {'things.myval': 1}},false,true)

или

db.coll.update({}, {$pull: {'things': {'myval': 1}}},false,true)

Попробуйте любой из них и увидите, какой из них работает, но вы должны использовать несколько параметров в обоих

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