2015-04-23 2 views
4

Предположим, у меня есть документ, какВ массиве поддокументе MongoDB есть ли способ, чтобы добавить новое поле в каждой subcoument

{ 
    "_id" : 5, 
    "rows": [ 
     { "id" : "aab", "value":100}, 
     { "id" : "aac", "value":400}, 
     { "id" : "abc", "value":200}, 
     { "id" : "xyz", "value":300} 
    ] 
} 

и мне нужно, чтобы добавить новый ключ в каждом суб документе «Статус»: 1 и результат должен быть похож

{ 
    "_id" : 5, 
    "rows": [ 
     { "id" : "aab", "value":100, "status":1}, 
     { "id" : "aac", "value":400, "status":1}, 
     { "id" : "abc", "value":200, "status":1}, 
     { "id" : "xyz", "value":300, "status":1} 
    ] 
} 

Как я могу сделать это с помощью одного запроса на обновление?

ответ

1

Mongo positional operator с $elemMatch с проблемой;

Оператор $ может обновить первый элемент массива, который соответствует нескольким критериям запроса, указанным с помощью оператора $ elemMatch().

Таким образом, в этом случае с использованием запроса mongo вы должны обновлять только конкретные критерии соответствия. Если вы установили rows.aac в матче, то вы будете добавлять status:1 в row.aac массиве проверить запрос, как показано ниже:

db.collectionName.update({ 
    "_id": 5, 
    "rows": { 
    "$elemMatch": { 
     "id": "abc" 
    } 
    } 
}, { 
    $set: { 
    "rows.$.status": 1 
    } 
}, true, false) // here you insert new field so upsert true 

mongo update, показывающие, как upsert и multi работ.

Но все же вы хотите обновить все документы, тогда вы должны использовать некоторые programming code или некоторые script. Ниже обновления кода все данные с помощью cursor forEach:

db.collectionName.find().forEach(function(data) { 
    for (var ii = 0; ii < data.rows.length; ii++) { 
    db.collectionName.update({ 
     "_id": data._id, 
     "rows.id": data.rows[ii].id 
    }, { 
     "$set": { 
     "rows.$.status": 1 
     } 
    }, true, false); 
    } 
}) 

Если ваши документы размером более лучший способ использовать mongo bulk update ниже код показывает, как обновить с помощью Монго навалом:

var bulk = db.collectionName.initializeOrderedBulkOp(); 
var counter = 0; 
db.collectionName.find().forEach(function(data) { 
    for (var ii = 0; ii < data.rows.length; ii++) { 

    var updatedDocument = { 
     "$set": {} 
    }; 

    var setStatus = "rows." + ii + ".status"; 
    updatedDocument["$set"][setStatus] = 101; 
    // queue the update 
    bulk.find({ 
     "_id": data._id 
    }).update(updatedDocument); 
    counter++; 
    // re-initialize every 1000 update statements 
    if (counter % 1000 == 0) { 
     bulk.execute(); 
     bulk = db.collectionName.initializeOrderedBulkOp(); 
    } 
    } 

}); 
// Add the rest in the queue 
if (counter % 1000 != 0) 
    bulk.execute(); 
Смежные вопросы