Yonatan Shorani
Yonatan Shorani

Reputation: 67

Push object into array if exists(checking by field) otherwise set object in MongoDB

This is the document I currently have:

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

I would like the push new user to the array if is not exists, And if the userId exists and the internalUserId different I want to update it

So if i got userId:"1111111" and internalUserId:"bbbb" The doc will be:

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

and if i got userId:"44444" and internalUserId:"bbbb" The doc will be

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

I tryid to do something like that:

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)

But In a situation that is the internalUserId different it adds new item not update it

Thanks!

Upvotes: 1

Views: 426

Answers (2)

Clement Amarnath
Clement Amarnath

Reputation: 5466

ArrayFilter is a new feature introduced in version 3.6, using that we can use this feature with update. Use $[identifier]

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

Upvotes: 1

gaurav singh
gaurav singh

Reputation: 1416

try this in 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});
       }

Upvotes: 1

Related Questions