Как обновить все документы с полем, равным длине другого поля в Mongo - PullRequest
0 голосов
/ 06 мая 2020

Я знаю, что могу сделать что-то подобное, чтобы обновить поле до указанного c значения:

db.coll.update({},{ $set: {'fieldName': 'fieldValue' } }, { multi:true });

Однако мне нужно обновить значение поля, равное количеству значений в поле массива того же документа. Я знаю, что для этого, вероятно, требуется агрегатная функция, но я новее Mon go и мог бы использовать некоторую помощь при построении запроса. Это также необходимо сделать для каждого документа в коллекции.

Ответы [ 2 ]

1 голос
/ 06 мая 2020

Предположим, что наша коллекция выглядит так:

{
        "_id" : 1
        "array" : [
                1,
                2,
                3
        ]
},
{       "_id" : 2,
        "array" : [
                1
         ]
},
{
        "_id" : 3
        "array" : [
                1,
                2,
                3,
                4,
                5,
                6
        ]
}

Требуется запрос:

db.collection.update({},[{$set: {size: {$size: '$array'}}}], {multi: true})

Ниже будет обновленная коллекция:

{
        "_id" : 1,
        "array" : [
                1,
                2,
                3
        ],
        "size" : 3
}
{
        "_id" : 2,
        "array" : [
                1
        ],
        "size" : 1
}
{
        "_id" : 3,
        "array" : [
                1,
                2,
                3,
                4,
                5,
                6
        ],
        "size" : 6
}
0 голосов
/ 06 мая 2020

Запрос, который у меня сработал:

var bulkOp = db.posts.initializeUnorderedBulkOp(); 
var count = 0;

db.posts.aggregate([
    { "$match": { 
        "_likes": { "$exists": true }
    }}, 
    { "$project": { "likeCount": { "$size": "$_likes" } } }
]).forEach(function(doc) { 
        bulkOp.find({ "_id": doc._id }).updateOne({ 
            "$set": { "likeCount": NumberInt(doc.likeCount) }
        });
        count++;
        if (count % 200 === 0) {
            // Execute per 200 operations and re-init
            bulkOp.execute();
            bulkOp = db.posts.initializeUnorderedBulkOp();
        }
})

// Clean up queues
if (count > 0) { 
    bulkOp.execute();
}
...