2016-05-14 3 views
-1

Gibt es einen einfachen Weg, ein Array-Element an seiner Position zu finden. Wo Position in demselben Dokument als anderes Feld definiert ist.Ermittelt ein Array-Element nach Position, die in demselben Dokument definiert ist wie ein anderes Feld in mongoDB

Beispiel Dokument:

{ 
    _id:"123", 
    "elementPosition": 3, 
    "users": [ 
       { 
       "username": "abcd" 
       }, 
       { 
       "username": "qweqw" 
       }, 
       { 
       "username": "fdsfsd" 
       }, 
       { 
       "username": "dsfvd" 
       } 
    ] 

} 

Weitere, wenn es eine einfache Möglichkeit ist dann auch in effizienter Weise unter Betrieb zu tun:

  1. Updaate Dokument wo users.elementPosition.username = "ABCD" und updaten "users.elementPosition.username" = "wxyz"

*** elementPosition aus demselben Dokument.

Ich habe so viele Möglichkeiten ausprobiert. Einer von ihnen wurde get ElementPosition bekommen und dann prüfen, ob Dokumente mit dieser ElementPosition übereinstimmen oder nicht. Aber das ist dreckig und langwierig.

Versucht, ElementPosition als Variable in einer einzelnen Abfrage "user."+elementPosition+".username" zu verwenden, hat aber nicht funktioniert.

Auch andere Art der Aggregatabfragen versucht, aber keine guten Ergebnisse erhalten. projizieren $elementPosition auf die nächste Stufe und verwenden Sie das, um bestimmte Position Dokument abrufen, aber nicht bekommen, was ich will.

+0

ein Grund für die Abstimmung unten die Frage? –

Antwort

1

Mit dem $arrayElemAt Operator:

db.collection.aggregate(
    {$match : {_id: "123"} }, 
    {$project : {username: {$arrayElemAt: [ "$users.username", "$elementPosition" ]}}}) 
+0

Danke für Ihre Antwort. Nützlich ... Das letzte Ziel besteht darin, das Element im Array an der im selben Dokument definierten Position zu aktualisieren. –

1

Ihre Follow-up-Frage Adressierung, wo Sie die Dokumente aktualisieren möchten, deren username = "abcd" zu "wxyz" die Position im gleichen Dokument definiert, können Sie die bulkWrite() Methode verwenden um das Update effizient durchzuführen. Im Folgenden wird gezeigt, wie man mit MongoDB 3.2 gehen oder größer:

var bulkUpdateOperations = [], 
    counter = 0, 
    setObj = {}; 

db.collection.find({ 
    "users.username": "abcd", 
    "elementPosition": { "$exists": true } 
}).forEach(function(doc) { 
    setObj["users."+ doc.elementPosition +".username"] = "wxyz"; 
    bulkUpdateOperations.push({ 
     "updateOne": { 
      "filter": { "_id": doc._id }, 
      "update": { "$set": setObj } 
     } 
    }); 

    if (counter % 1000 == 0) { 
     db.collection.bulkWrite(bulkUpdateOperations); 
     bulkUpdateOperations = []; 
    } 
}) 

if (counter % 1000 != 0) { db.collection.bulkWrite(bulkUpdateOperations); } 

Wenn älteren Versionen von MongoDB dh v2.6 mit oder 3.0 dann die Bulk Operations API verwendet werden, die in diesen Versionen unterstützt:

var bulk = [], 
    counter = 0, 
    setObj = {}; 

db.collection.find({ 
    "users.username": "abcd", 
    "elementPosition": { "$exists": true } 
}).forEach(function(doc) { 
    setObj["users."+ doc.elementPosition +".username"] = "wxyz"; 
    bulk.find({ "_id": doc._id }).updateOne({ "$set": setObj }); 

    if (counter % 1000 == 0) { 
     bulk.execute(); 
     bulk = db.collection.initializeUnorderedBulkOp(); 
    } 
}); 

if (counter % 1000 != 0) { bulk.execute(); }; 
+0

Danke für Ihre Antwort. Nicht das: update die Dokumente, deren username = "abcd" zu "wxyz" ... Ich will dies: aktualisieren Sie die Dokumente, wo users.elementPosition.username = "abcd" und update "users.elementPosition.username" = " wxyz " " user.elementPosition.username "=" abcd "hier elementPosition ist in demselben Dokument definiert. Scheint, das passende Dokument zu erhalten, kann ich die [Atchoum's] (und http://stackoverflow.com/a/37250463/5236174) Lösung und Ihre Dokumente aktualisieren. –

Verwandte Themen