sql >> Base de Datos >  >> NoSQL >> MongoDB

Actualice el campo MongoDB usando el valor de otro campo

La mejor manera de hacer esto es en la versión 4.2+ que permite el uso de canalización de agregación en la actualización documento y el updateOne , updateMany o update métodos de recolección. Tenga en cuenta que este último ha quedado obsoleto en la mayoría, si no en todos, los controladores de idiomas.

MongoDB 4.2+

La versión 4.2 también introdujo el $set operador de etapa de canalización que es un alias para $addFields . Usaré $set aquí como mapas con lo que estamos tratando de lograr.

db.collection.<update method>(
    {},
    [
        {"$set": {"name": { "$concat": ["$firstName", " ", "$lastName"]}}}
    ]
)

Tenga en cuenta los corchetes en el segundo argumento del método que define una canalización de agregación en lugar de un documento de actualización simple. El uso de un documento simple no funcione correctamente.

MongoDB 3.4+

En 3.4+ puede usar $addFields y el $out operadores de tubería de agregación.

db.collection.aggregate(
    [
        { "$addFields": { 
            "name": { "$concat": [ "$firstName", " ", "$lastName" ] } 
        }},
        { "$out": "collection" }
    ]
)

Tenga en cuenta que esto no actualiza su colección, sino que reemplaza la colección existente o crea una nueva. También para las operaciones de actualización que requieren "encasillamiento" necesitará procesamiento del lado del cliente, y dependiendo de la operación, es posible que deba usar find() método en lugar de .aggreate() método.

MongoDB 3.2 y 3.0

La forma en que hacemos esto es por $project escribiendo nuestros documentos y usando el $concat operador de agregación de cadenas para devolver la cadena concatenada. A partir de ahí, itera el cursor y usa el $set operador de actualización para agregar el nuevo campo a sus documentos usando operaciones masivas para una máxima eficiencia.

Consulta de agregación:

var cursor = db.collection.aggregate([ 
    { "$project":  { 
        "name": { "$concat": [ "$firstName", " ", "$lastName" ] } 
    }}
])

MongoDB 3.2 o posterior

a partir de esto, debe usar bulkWrite método.

var requests = [];
cursor.forEach(document => { 
    requests.push( { 
        'updateOne': {
            'filter': { '_id': document._id },
            'update': { '$set': { 'name': document.name } }
        }
    });
    if (requests.length === 500) {
        //Execute per 500 operations and re-init
        db.collection.bulkWrite(requests);
        requests = [];
    }
});

if(requests.length > 0) {
     db.collection.bulkWrite(requests);
}

MongoDB 2.6 y 3.0

A partir de esta versión, debe usar el ahora obsoleto Bulk API y sus métodos asociados.

var bulk = db.collection.initializeUnorderedBulkOp();
var count = 0;

cursor.snapshot().forEach(function(document) { 
    bulk.find({ '_id': document._id }).updateOne( {
        '$set': { 'name': document.name }
    });
    count++;
    if(count%500 === 0) {
        // Excecute per 500 operations and re-init
        bulk.execute();
        bulk = db.collection.initializeUnorderedBulkOp();
    }
})

// clean up queues
if(count > 0) {
    bulk.execute();
}

MongoDB 2.4

cursor["result"].forEach(function(document) {
    db.collection.update(
        { "_id": document._id }, 
        { "$set": { "name": document.name } }
    );
})