MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

Aggiorna il campo MongoDB utilizzando il valore di un altro campo

Il modo migliore per farlo è nella versione 4.2+ che consente l'utilizzo della pipeline di aggregazione nell'aggiornamento documento e updateOne , updateMany o update metodi di raccolta. Tieni presente che quest'ultimo è stato deprecato nella maggior parte se non in tutte le lingue dei driver.

MongoDB 4.2+

La versione 4.2 ha anche introdotto il $set operatore della fase della pipeline che è un alias per $addFields . Userò $set qui come mappa con ciò che stiamo cercando di ottenere.

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

Si noti che le parentesi quadre nel secondo argomento del metodo che definisce una pipeline di aggregazione invece di un semplice documento di aggiornamento. L'utilizzo di un documento semplice non funzionano correttamente.

MongoDB 3.4+

In 3.4+ puoi usare $addFields e il $out operatori di pipeline di aggregazione.

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

Tieni presente che questo non aggiorna la tua raccolta, ma sostituisce la raccolta esistente o ne crea una nuova. Anche per le operazioni di aggiornamento che richiedono "typecasting" sarà necessaria l'elaborazione lato client e a seconda dell'operazione, potrebbe essere necessario utilizzare find() metodo invece di .aggreate() metodo.

MongoDB 3.2 e 3.0

Il modo in cui lo facciamo è tramite $project mentendo i nostri documenti e usando il $concat operatore di aggregazione di stringhe per restituire la stringa concatenata. Da lì, quindi scorrere il cursore e usa il $set update per aggiungere il nuovo campo ai tuoi documenti utilizzando operazioni collettive per la massima efficienza.

Query di aggregazione:

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

MongoDB 3.2 o successivo

da questo, devi usare il bulkWrite metodo.

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 e 3.0

A partire da questa versione, devi utilizzare il Bulk ora deprecato API e metodi associati.

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 } }
    );
})