如果存在,则将对象推送到数组(按字段检查),否则在MongoDB中设置对象

时间:2018-04-24 09:18:52

标签: mongodb reactivemongo play-reactivemongo

这是我目前的文件:

{ 
    "_id" : ObjectId("5adef141502f49a6a2812016"), 
    "productId" : "123456", 
    "users" : [
        {
            "userId" : "1111111", 
            "internalUserId" : "azxcvdd"
        }, 
        {
            "userId" : "2222222", 
            "internalUserId" : "dsdasd"
        }
    ]
}

如果不存在,我希望将新用户推送到数组中, 如果userId存在且internalUserId不同,我想更新它

所以,如果我有userId:“1111111”和internalUserId:“bbbb” 该文件将是:

{ 
    "_id" : ObjectId("5adef141502f49a6a2812016"), 
    "productId" : "123456", 
    "users" : [
        {
            "userId" : "1111111", 
            "internalUserId" : "bbbb"
        }, 
        {
            "userId" : "2222222", 
            "internalUserId" : "dsdasd"
        }
    ]
}

如果我有userId:“44444”和internalUserId:“bbbb” 该文件将是

{ 
    "_id" : ObjectId("5adef141502f49a6a2812016"), 
    "productId" : "123456", 
    "users" : [
        {
            "userId" : "1111111", 
            "internalUserId" : "bbbb"
        }, 
        {
            "userId" : "2222222", 
            "internalUserId" : "dsdasd"
        }, 
        {
            "userId" : "44444", 
            "internalUserId" : "bbbb"
        }
    ]
}

我尝试做类似的事情:

val selector = Json.obj("productId" -> productId)
val modifier = Json.obj("$addToSet" -> Json.obj("users" -> Json.obj("userId" -> user.userId, "internalUserId" -> user.internalUserId)))
        for {
          collection <- collectionFut
          writeResult <- collection.findAndUpdate(selector, modifier, upsert = true)

但是在internalUserId不同的情况下,它会添加新项目而不更新它

谢谢!

2 个答案:

答案 0 :(得分:1)

在mongo shell中尝试这个

    var cur = db.col.aggregate([ 
   { "$unwind": "$users" }
     ]);


     while (cur.hasNext()) {
     var doc = cur.next();
      db.col.update({ "users.userId": "1111" },
              { "$set": { "users.internalUserId": "bbbb" }},
              {'upsert':true});
       }

答案 1 :(得分:0)

ArrayFilter是3.6版中引入的新功能,使用此功能我们可以将此功能与update一起使用。使用$[identifier]

db.collection.update(
   { "users.userId" : "1111111" },
   { $set: { "users.$[elem].internalUserId"  : "bbbb"} },
   { arrayFilters: [ { "elem.userId": "1111111" } } ], upsert: true }
)