Saltar al contenido

Actualice el campo MongoDB usando el valor de otro campo

Al fin después de tanto batallar ya encontramos la respuesta de este atasco que muchos usuarios de este sitio han presentado. Si deseas compartir algo más no dudes en dejar tu comentario.

Solución:

La mejor manera de hacer esto es en la versión 4.2+ que permite el uso de canalización de agregación en el documento de actualización y el updateOne, updateMany o update método 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 la $set operador de etapa de tubería que es un alias para $addFields. usaré $set aquí como mapas con lo que estamos tratando de lograr.

db.collection.(
    ,
    [
        "$set": "name":  "$concat": ["$firstName", " ", "$lastName"]
    ]
)

MongoDB 3.4+

En 3.4+ puedes usar $addFields y el $out operadores de tuberías 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 operaciones de actualización que requieran “type casting” necesitará procesamiento del lado del cliente, y dependiendo de la operación, es posible que necesite utilizar el find() método en lugar del .aggreate() método.

MongoDB 3.2 y 3.0

La forma en que hacemos esto es por $projecting nuestros documentos y utilizar el $concat string operador de agregación para devolver el concatenado string. 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 más reciente

a partir de esto, es necesario utilizar el 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();

Mongo DB 2.4

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

Deberías iterar. Para su caso específico:

db.person.find().snapshot().forEach(
    function (elem) 
        db.person.update(
            
                _id: elem._id
            ,
            
                $set: 
                    name: elem.firstname + ' ' + elem.lastname
                
            
        );
    
);

Aparentemente, hay una manera de hacer esto de manera eficiente desde MongoDB 3.4, vea la respuesta de styvane.


Respuesta obsoleta a continuación

No puede hacer referencia al documento en sí mismo en una actualización (todavía). Deberá iterar a través de los documentos y actualizar cada documento usando una función. Vea esta respuesta para ver un ejemplo, o esta para el lado del servidor eval().

Valoraciones y reseñas

Agradecemos que quieras añadir valor a nuestro contenido cooperando tu veteranía en los comentarios.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *