MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

Wie bekomme ich den neuen Wert nach einer Aktualisierung in einem eingebetteten Array zurück?

Wenn Sie MongoDB 3.0 oder neuer verwenden, müssen Sie .findOneAndUpdate() verwenden und verwenden Sie projection Option, um die Teilmenge der zurückzugebenden Felder anzugeben. Sie müssen auch returnNewDocument festlegen auf true . Natürlich müssen Sie das $elemMatch verwenden Projektionsoperator hier, da Sie keine Positionsprojektion verwenden und das neue Dokument zurückgeben können.

Wie jemand darauf hingewiesen hat:

Sie sollten .findOneAndUpdate() verwenden weil .findAndModify() ist in jedem offiziellen Sprachtreiber als veraltet markiert. Die andere Sache ist, dass die Syntax und die Optionen für alle Treiber für .findOneAndUpdate() ziemlich konsistent sind . Mit .findAndModify() verwenden die meisten Treiber nicht dasselbe einzelne Objekt mit den Schlüsseln „query/update/fields“. Es ist also etwas weniger verwirrend, wenn sich jemand für eine andere Sprache bewirbt, um konsistent zu sein. Standardisierte API-Änderungen für .findOneAndUpdate() entsprechen eigentlich eher der Serverversion 3.x als 3.2.x. Der vollständige Unterschied besteht darin, dass die Shell-Methoden tatsächlich (ausnahmsweise!) bei der Implementierung der Methode hinter den anderen Treibern zurückgeblieben sind. Die meisten Treiber hatten also tatsächlich einen großen Release-Bump, der dem 3.x-Release mit solchen Änderungen entsprach.

db.collection.findOneAndUpdate( 
    { 
        "_id": ObjectId("56d6a7292c06e85687f44541"), 
         "rankings._id" : ObjectId("46d6a7292c06e85687f55543") 
    },  
    { $inc : { "rankings.$.score" : 1 } },  
    { 
        "projection": { 
            "rankings": { 
                "$elemMatch": { "_id" : ObjectId("46d6a7292c06e85687f55543") } 
            }
        }, 
        "returnNewDocument": true 
    }
)

Ab MongoDB 3.0 müssen Sie findAndModify verwenden und die fields Optionen müssen Sie auch new setzen auf true in anderen, um den neuen Wert zurückzugeben.

db.collection.findAndModify({   
    query: { 
        "_id": ObjectId("56d6a7292c06e85687f44541"), 
        "rankings._id" : ObjectId("46d6a7292c06e85687f55543") 
    },     
    update: { $inc : { "rankings.$.score" : 1 } },       
    new: true,  
    fields: { 
        "rankings": { 
            "$elemMatch": { "_id" : ObjectId("46d6a7292c06e85687f55543") }
        }  
    }
})

Beide Abfragen ergeben:

{
        "_id" : ObjectId("56d6a7292c06e85687f44541"),
        "rankings" : [
                {
                        "_id" : ObjectId("46d6a7292c06e85687f55543"),
                        "name" : "Ranking 2",
                        "score" : 11
                }
        ]
}