549 Stimmen

MongoDB-Feld mit dem Wert eines anderen Feldes aktualisieren

Ist es in MongoDB möglich, den Wert eines Feldes mit dem Wert eines anderen Feldes zu aktualisieren? Die entsprechende SQL-Anweisung wäre etwa wie folgt:

UPDATE Person SET Name = FirstName + ' ' + LastName

Und der MongoDB-Pseudocode würde lauten:

db.person.update( {}, { $set : { name : firstName + ' ' + lastName } );

17voto

Aldo Punkte 1119

Diesbezüglich 回答 Die Snapshot-Funktion ist in Version 3.6 veraltet, wie hier beschrieben アップデート . Ab Version 3.6 ist es also möglich, den Vorgang auf diese Weise durchzuführen:

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

10voto

Yuvaraj Anbarasan Punkte 341

update() Methode nimmt die Aggregationspipeline als Parameter wie

db.collection_name.update(
  {
    // Query
  },
  [
    // Aggregation pipeline
    { "$set": { "id": "$_id" } }
  ],
  {
    // Options
    "multi": true // false when a single doc has to be updated
  }
)

Das Feld kann mit Hilfe der Aggregationspipeline mit vorhandenen Werten gesetzt oder aufgehoben werden.

Note : verwenden $ mit Feldname, um das zu lesende Feld anzugeben.

8voto

Chris Gibb Punkte 775

Ich habe die obige Lösung ausprobiert, aber ich fand sie für große Datenmengen ungeeignet. Dann habe ich die Stream-Funktion entdeckt:

MongoClient.connect("...", function(err, db){
    var c = db.collection('yourCollection');
    var s = c.find({/* your query */}).stream();
    s.on('data', function(doc){
        c.update({_id: doc._id}, {$set: {name : doc.firstName + ' ' + doc.lastName}}, function(err, result) { /* result == true? */} }
    });
    s.on('end', function(){
        // stream can end before all your updates do if you have a lot
    })
})

2voto

Chris Bloom Punkte 3425

So sieht es aus, wenn wir ein Feld in ein anderes für ~150_000 Datensätze kopieren. Es dauerte etwa 6 Minuten, ist aber immer noch deutlich weniger ressourcenintensiv als die Instanziierung und Iteration der gleichen Anzahl von Ruby-Objekten gewesen wäre.

js_query = %({
  $or : [
    {
      'settings.mobile_notifications' : { $exists : false },
      'settings.mobile_admin_notifications' : { $exists : false }
    }
  ]
})

js_for_each = %(function(user) {
  if (!user.settings.hasOwnProperty('mobile_notifications')) {
    user.settings.mobile_notifications = user.settings.email_notifications;
  }
  if (!user.settings.hasOwnProperty('mobile_admin_notifications')) {
    user.settings.mobile_admin_notifications = user.settings.email_admin_notifications;
  }
  db.users.save(user);
})

js = "db.users.find(#{js_query}).forEach(#{js_for_each});"
Mongoid::Sessions.default.command('$eval' => js)

0voto

Yi Xiang Chong Punkte 596

Avec MongoDB Version 4.2+ sind Aktualisierungen flexibler, da sie die Verwendung von Aggregationspipelines in ihrer update , updateOne y updateMany . Sie können nun Ihre Dokumente mit Hilfe der Aggregationsoperatoren umwandeln und dann aktualisieren, ohne dass Sie explizit angeben müssen, welche $set Befehl (stattdessen verwenden wir $replaceRoot: {newRoot: "$$ROOT"} )

Hier verwenden wir die Aggregatabfrage, um den Zeitstempel aus dem ObjectID-Feld "_id" von MongoDB zu extrahieren und die Dokumente zu aktualisieren (ich bin kein SQL-Experte, aber ich denke, dass SQL keine automatisch generierte ObjectID mit einem Zeitstempel zur Verfügung stellt.)

var collection = "person"

agg_query = [
    {
        "$addFields" : {
            "_last_updated" : {
                "$toDate" : "$_id"
            }
        }
    },
    {
        $replaceRoot: {
            newRoot: "$$ROOT"
        } 
    }
]

db.getCollection(collection).updateMany({}, agg_query, {upsert: true})

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X