sql >> Databasteknik >  >> NoSQL >> MongoDB

Uppdatera MongoDB-fältet med värdet av ett annat fält

Det bästa sättet att göra detta är i version 4.2+ som tillåter användning av aggregeringspipeline i uppdateringen dokumentet och updateOne , updateMany eller update insamlingsmetoder. Notera att det senare har utfasat i de flesta om inte alla språk drivrutiner.

MongoDB 4.2+

Version 4.2 introducerade också $set pipeline stage operator som är ett alias för $addFields . Jag kommer att använda $set här som det kartor med det vi försöker uppnå.

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

Observera att hakparenteser i det andra argumentet till metoden som definierar en aggregeringspipeline istället för ett vanligt uppdateringsdokument. Att använda ett vanligt dokument inte fungerar korrekt.

MongoDB 3.4+

I 3.4+ kan du använda $addFields och $out aggregeringspipelineoperatörer.

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

Observera att detta inte uppdaterar din samling utan istället ersätter den befintliga samlingen eller skapar en ny. Även för uppdateringsoperationer som kräver "typecasting" behöver du bearbetning på klientsidan, och beroende på operationen kan du behöva använda find() metoden istället för .aggreate() metod.

MongoDB 3.2 och 3.0

Sättet vi gör detta på är genom $project använda våra dokument och använda $concat strängaggregationsoperator för att returnera den sammanlänkade strängen. Därifrån itererar du sedan markören och använd $set uppdatera operatorn för att lägga till det nya fältet i dina dokument med bulkoperationer för maximal effektivitet.

Aggregationsfråga:

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

MongoDB 3.2 eller senare

från detta måste du använda bulkWrite metod.

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

Från den här versionen måste du använda den nu utfasade Bulk API och dess associerade metoder.

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


  1. Vilket är det maximala antalet parametrar som skickas till $in-frågan i MongoDB?

  2. Tips för att hantera MongoDB på distans

  3. Redis sentinel vs clustering

  4. Hitta dokument i MongoDB vars med ett matrisfält är en delmängd av en frågematris