2016-03-11 57 views
5

鑑於以下MongoDB的集合:如何在嵌入式數組更新後獲取新值?

{ 
    "_id": ObjectId("56d6a7292c06e85687f44541"), 
    "name": "My ranking list", 
    "rankings": [ 
     { 
      "_id": ObjectId("46d6a7292c06e85687f55542"), 
      "name": "Ranking 1", 
      "score": 1 
     }, 
     { 
      "_id": ObjectId("46d6a7292c06e85687f55543"), 
      "name": "Ranking 2", 
      "score": 10 
     }, 
     { 
      "_id": ObjectId("46d6a7292c06e85687f55544"), 
      "name": "Ranking 3", 
      "score": 15 
     }, 
    ] 
} 

這是我如何增加給定名次的得分:

db.collection.update(
    { "_id": ObjectId("56d6a7292c06e85687f44541"), "rankings._id" : ObjectId("46d6a7292c06e85687f55543") }, 
    { $inc : { "rankings.$.score" : 1 } } 
); 

我如何獲得新的得分值?在之前的查詢中,我將第二個排名從10增加到了11 ...如何在更新後獲取此新值?

+2

你可以使用['findAndModify'(https://docs.mongodb.org/manual/reference/command/findAndModify/) – BatScream

回答

9

如果您在MongoDB的3.0或更新版本,您需要使用.findOneAndUpdate()和使用projection選項指定字段返回的子集。您還需要將returnNewDocument設置爲true。當然,您需要在這裏使用$elemMatch投影算子,因爲您不能使用位置投影並返回新文檔。

正如有人指出:

您應該使用.findOneAndUpdate()因爲在每一個官方語言司機棄用.findAndModify()被highlighed。另一件事是,在.findOneAndUpdate()的驅動程序中,語法和選項非常一致。使用.findAndModify()時,大多數驅動程序不會在「查詢/更新/字段」鍵中使用相同的單個對象。因此,當某人應用另一種語言以保持一致時,它會少一些混淆。 .findOneAndUpdate()的標準化API更改實際上對應於服務器版本3.x而不是3.2.x.完全的區別在於shell方法在實現該方法時實際上落後於其他驅動程序(只有一次!)。因此,大多數驅動程序實際上都有一個與3.x版本相對應的主要發行版緩存,並進行了這些更改

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

從MongoDB的3.0起,您需要使用findAndModifyfields選項還需要設置newtrue其他返回新值。

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

兩個查詢產生:

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