Как обновить значения во вложенном массиве? - PullRequest
0 голосов
/ 26 сентября 2018

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

У меня есть документ, содержащий некоторые вложенные данные.В настоящее время product и customer являются массивами, я бы предпочел иметь их как прямые ObjectID.

    {
            "_id" : ObjectId("5bab713622c97440f287f2bf"),
            "created_at" : ISODate("2018-09-26T13:44:54.431Z"),
            "prod_line" : ObjectId("5b878e4c22c9745f1090de66"),
            "entries" : [
                    {
                            "order_number" : "123",
                            "product" : [
                                    ObjectId("5ba8a0e822c974290b2ea18d")
                            ],
                            "customer" : [
                                    ObjectId("5b86a20922c9745f1a6408d4")
                            ],
                            "quantity" : "14"
                    },
                    {
                            "order_number" : "456",
                            "product" : [
                                    ObjectId("5b878ed322c9745f1090de6c")
                            ],
                            "customer" : [
                                    ObjectId("5b86a20922c9745f1a6408d5")
                            ],
                            "quantity" : "12"
                    }
            ]
    }

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

    db.Document.find().forEach(function(doc){
            doc.entries.forEach(function(entry){
                    var entry_id = entry.product[0]
                    db.Document.update({_id: doc._id}, {$set:{'product': entry_id}});
                    print(entry_id)
                    })
    })

С помощью этого запроса он устанавливает product в корне объекта, не совсем то, на что я надеялся.То, что я надеялся сделать, это перебирать записи и изменять каждый отдельный product и customer, чтобы он был только их ObjectId, а не массивом.Можно ли сделать это через оболочку Монго или мне нужно искать другой способ сделать это?Спасибо!

Ответы [ 3 ]

0 голосов
/ 26 сентября 2018

Чтобы выполнить указанное вами поведение, вам просто нужно немного изменить структуру запроса.Посмотрите здесь для конкретной документации MongoDB о том, как это сделать.Я также предложу обновить код ниже:

db.Document.find().forEach(function(doc) {
    doc.entries.forEach(function(entry, index) {
        var productElementKey = 'entries.' + index + '.product';
        var productSetObject = {};
        productSetObject[productElementKey] = entry.product[0];
        db.Document.update({_id: doc._id}, {$set: productSetObject});
        print(entry_id)
    })
})

Проблема, с которой вы столкнулись, заключается в том, что вы не обновляли определенный элемент в массиве entries, а добавляли новый ключ кверхний уровень документа с именем product.Как правило, чтобы установить значение внутреннего документа в массиве, сначала необходимо указать ключ массива (в данном случае entries), а затем второй ключ внутреннего документа (в этом случае product).Поскольку вы пытаетесь установить определенные элементы в массиве entries, вам также необходимо указать индекс в вашем объекте запроса, как я уже указывал выше.

Чтобы обновить ключ customer во внутреннемдокументы, просто отключите product для customer в моем коде выше.

0 голосов
/ 26 сентября 2018

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

db.documents.find().snapshot().forEach(function (elem) {
    elem.entries.forEach(function(entry){

        db.documents.update({
                _id: elem._id,
                "entries.order_number": entry.order_number
            }, {
                $set: {
                    "entries.$.product" : entry.product[0],
                    "entries.$.customer" : entry.customer[0]
                }
            }
        );
    });
});

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

0 голосов
/ 26 сентября 2018

Вы пытаетесь добавить свойство 'product' прямо в ваш документ с помощью этой строки

db.Document.update({_id: doc._id}, {$set:{'product': entry_id}});

Попробуйте сначала изменить все ваши записи, а затем обновите документ с помощью этого нового массива записей.

db.Document.find().forEach(function(doc){
        let updatedEntries = [];
        doc.entries.forEach(function(entry){
            let newEntry = {};

            newEntry["order_number"] = entry.order_number;
            newEntry["product"] = entry.product[0];
            newEntry["customer"] = entry.customer[0];
            newEntry["quantity"] = entry.quantity;

            updatedEntries.push(newEntry);
       })
       db.Document.update({_id: doc._id}, {$set:{'entries': updatedEntries}});
})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...