Ram Viswanathan
Ram Viswanathan

Reputation: 201

mongo java for finding and upserting a nested array element

I have a mongo collection element with the following structure

{
    "_id" : ObjectId("568eaba5e4b0fa3cdf9aaf85"),
    "type" : "X",
    "textId" : "568eaba5e4b0fa3cdf9aaf84",
    "createDate" : "2016-01-07 18:17:09",
    "likes" : [ 
        {
            "creatorName" : "ABCD",
            "creationDate" : "2016-01-10 19:48:37",
            "likeId" : "56932615569aae9d1459eb9b"
        }
     ]
}

My need is as follows: When a new like is posted by a creatorName for a particular element identified by textId, I should a) check if the like is already present for the creatorName for the specific textId object. If present, do nothing b) if the like is not present, I should insert a new element into the likes array

How to do this effectively in java? I see that we have an update method and a findAndModify method. Which one to use and how to handle this in the most effective manner?

Upvotes: 1

Views: 461

Answers (2)

Valijon
Valijon

Reputation: 13103

You may insert likes by update function with query condition:


db.collection.update({
    "textId" : "568eaba5e4b0fa3cdf9aaf84", 
    "likes.likeId": {"$nin": ["56932615569aae9d1459eb10"]}, 
    "likes.creatorName" : {"$nin": ["ABCE"]}
    },  
    {
        "$push" : {
            "likes" : {
                 "creatorName" : "ABCE",
                 "creationDate" : "2016-01-10 21:48:37",
                 "likeId" : "56932615569aae9d1459eb10"
             }
        }
    }
)

Updated 1 existing record(s)

If you try to add new like for the same creatorName, it will not update.

db.collection.update({
    "textId" : "568eaba5e4b0fa3cdf9aaf84", 
    "likes.likeId": {"$nin": ["56932615569aae9d1459eb11"]}, 
    "likes.creatorName" : {"$nin": ["ABCD"]}
    },  
    {
        "$push" : {
            "likes" : {
                 "creatorName" : "ABCD",
                 "creationDate" : "2016-01-11 19:48:37",
                 "likeId" : "56932615569aae9d1459eb11"
             }
        }
    }
)

Updated 0 record(s)

Java driver does not give any performance advantage.

If you add index depending on query condition, it will improve the performance. (Needs only once)

db.colecction.createIndex({"textId":1, "likes.likeId":1, "likes.creatorName":1}) 

Upvotes: 0

nach0
nach0

Reputation: 389

Unique indexes

You can create a unique index as follows:

db.collection.createIndex( { "likes.creatorName": 1 }, { unique: true } )

As official documentation says:

A unique index causes MongoDB to reject all documents that contain a duplicate value for the indexed field.

if the creatorName already exists, write operation will fail as follows:

WriteResult({
    "nInserted" : 0,
    "writeError" : {
        "code" : 11000,
        "errmsg" : "E11000 duplicate key error index: test.collection.$likes.creatorName_1 dup key: { : 1.0 }"
    }
})

Then, you don't need to worry about if creatorName already exists or not.

On the other hand, if you need to know if the creatorName already exists, you need to have a look to the WriteResult returned value (0 or 1).

Upvotes: 1

Related Questions