Пн goose - обновить каждый вложенный документ в массиве (node.js) - PullRequest
0 голосов
/ 14 января 2020

Я перечитал весь Google, но не смог найти правильный ответ. Очень надеюсь на вашу помощь!

Могу ли я обновить все вложенные документы в массиве items? Вот пример:

const newName = ['First', 'Second', 'Third']; 

{
_id: ObjectId('1')
items: [
    {
        _id: ObjectId('11'),
        name: ''
    },
    {
        _id: ObjectId('12')
        name: ''
    },
    {
        _id: ObjectId('13')
        name: ''
    }
]
}

Что я пытался сделать:

.update({ _id: ObjectId('1') }, {$set: { 'items.$.name': newName }},false,true);

Но это работает только тогда, когда newName является строкой и только для первого объекта в массиве. $[] сделать то же самое с одним исключением, в каждом объекте установлено одинаковое значение String. С массивом newName он вообще не работает.

Как я могу решить эту проблему? Искать каждый раз по объекту _id не вариант. Спасибо!

1 Ответ

0 голосов
/ 15 января 2020

Действительно, ваше текущее обновление будет обновлять только первый элемент в массиве с помощью позиционного оператора ($), а все элементы с одинаковым значением с помощью «всего позиционного оператора» ($ []). Я обнаружил, что множественное редактирование массивов / поддок немного сложнее с mon goose.

Я думаю, что есть пара способов, которыми вы могли бы go по этому поводу. Возможно, наивный (и не рекомендуемый) подход может заключаться в том, чтобы найти () обновляемый документ, а затем поработать над объектом документа, циклически изменяя массив, чтобы обновить каждый объект (используя стандартный итератор массива js для соответствия индексы со значениями массива обновления) перед вызовом save () в основном документе. Однако я считаю, что это может привести к риску того, что кто-то другой попытается обновить документ во время окна поиска, обновления и обратной записи, поскольку это не атомы c.

Второй, более безопасный вариант будет чтобы установить Model.bulkWrite () , который позволит вам обновить документ на месте с несколькими изменениями, используя массив updateOne 'ops'. Таким образом, вы найдете () массив / subdo c, который вы будете обновлять sh, создайте свой массив команд updateOne в js, отображая субдо c, пока вы не охватите все нужные вам массивы чтобы обновить, затем вызовите команду bulkWrite (), чтобы обновить все за один раз.

Надеюсь, это направит вас в правильном направлении. Удачи!

...