How to check more than 2 conditions in a single mongodb query?

1,239 views
Skip to first unread message

Deepesh Maheshwari

unread,
Aug 25, 2014, 5:30:19 AM8/25/14
to mongod...@googlegroups.com
Hi,

I have a scenario in which i need to update "count" field and "lastAccessDate" for a document when a user visits.

Old Scenario : 
That works fine as it has if-else condition.

db.userFrequency.update({"host" : "abc.com","sessionId" : "ff8378ed-ccda-4a75-b24b-4a4bb1153e39"},{"$set" : {"lastAccessDate":"20140825"},"$inc" : {"count":1}},{upsert:true})

Now, my requirement has changed,I need to update count like below

New Scenario : 

obj = db.userFrequency.update({"host" : "abc.com","sessionId" : "ff8378ed-ccda-4a75-b24b-4a4bb1153e39"});

if(obj!=null){
    
          // Increment Count only if a visitor hasn't visit today.
         if(obj.get("lastAccessDate" != todayDate))
        {
         
            db.userFrequency.update({"host" : "abc.com","sessionId" : "ff8378ed-ccda-4a75-b24b-4a4bb1153e39"},{"$set" : {"lastAccessDate": todayDate},"$inc" : {"count":1}},{upsert:true});
          
         }

         // If an user has already visited today, do nothing.
         else{
         
         }

}else{

     // Insert the document as it doesnt exists in collection.
    db.userFrequency.update({"host" : "abc.com","sessionId" : "ff8378ed-ccda-4a75-b24b-4a4bb1153e39"},{"$set" : {"lastAccessDate": todayDate},"$inc" : {"count":1}},{upsert:true});
}

My Problem : 
Previously, in old scenario, i can do operation in a single query but in new scenario, i am not able to do it in single query but in update with upsert option, there is only if {where clause}-else{update} condition is possible.

Please, suggest any way so i can do the new scenario in just a single db query because my data is in GB's, i cant afford 2 queries.

Thanks,
Deepesh

False McFakeman

unread,
Aug 25, 2014, 3:40:37 PM8/25/14
to mongod...@googlegroups.com
I think you could do this with the $lt or the $ne operators:

db.userFrequency.update({"host" : "abc.com","sessionId" : "ff8378ed-ccda-4a75-b24b-4a4bb1153e39", "lastAccessDate":{$lt : todayDate}},{"$set" : {"lastAccessDate":"20140825"},"$inc" : {"count":1}},{upsert:true})

Deepesh Maheshwari

unread,
Aug 26, 2014, 1:01:02 AM8/26/14
to mongod...@googlegroups.com
Hi,
It is not fulfilling the second if condition as i have secribed in the first post because if a user has visited today already,then its "lastAccessDate":todayDate.
So, when we comes to third condition,"lastAccessDate":{$lt : todayDate} , it fails and upsert the new entry.

False McFakeman

unread,
Aug 26, 2014, 2:29:38 PM8/26/14
to mongod...@googlegroups.com
I see, I didn't realize.

I don't know if this is good practice, but you could have made the _id a combination of the host and the sessionId, assuming that the sessionId uniquely identifies the user you're counting views from.  Then, including the _id in your update would make upsert fail if the doc already exists, but updates on docs with old dates would still work, and upsert where the doc doesn't yet exist would work.

Deepesh Maheshwari

unread,
Aug 28, 2014, 1:27:33 AM8/28/14
to mongod...@googlegroups.com
db.userFrequency.update({ "host" : "abc.com" , "lastAccessDate" : { "$lt" : "20140828"} , "sessionId" : "ff8378ed-ccda-4a75-b24b-4a4bb1153e39"},{ "$set" : { "lastAccessDate" : "20140828"} , "$inc" : { "count" : 1}},{upsert:true}) 

This is my sample query.This works fine if it is a new entry or "lastAccessDate"!=todayDate but if entry exists and "lastAccessDate"==todayDate, then ["lastAccessDate"!=todayDate] is evaluated to false and it will upsert new entry for same date.Please check it where i am wrong

Virendra Agarwal

unread,
Aug 28, 2014, 3:26:04 AM8/28/14
to mongod...@googlegroups.com

HI Mc,

update operation does not allow _id field in set.
Could you please tell us if there is a work around to it.

False McFakeman

unread,
Aug 28, 2014, 6:43:31 PM8/28/14
to mongod...@googlegroups.com
If you include the _id field not in the $set but rather in the query, then you would be able to do what you want.

The only problem is that you need to know what the _id value is.  If your _id were stored as a combination of the user and the host, you would always know the _id.  If you changed your schema to use something like:
_id : {host: "abc.com", sessionId: "ff837ed-ccda-4a75-b24b-4a4bb153e39"}

But it might not be worth it to do this just to fit this use case.  Nonetheless, it's the only thing I can imagine.

Asya Kamsky

unread,
Sep 2, 2014, 1:10:39 AM9/2/14
to mongodb-user
Have a unique index on host, sessionId.

Then when an insert is attempted (on upsert) it will fail (but that
will be expected).

Asya
> --
> You received this message because you are subscribed to the Google Groups
> "mongodb-user"
> group.
>
> For other MongoDB technical support options, see:
> http://www.mongodb.org/about/support/.
> ---
> You received this message because you are subscribed to the Google Groups
> "mongodb-user" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to mongodb-user...@googlegroups.com.
> To post to this group, send email to mongod...@googlegroups.com.
> Visit this group at http://groups.google.com/group/mongodb-user.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/mongodb-user/6182f810-36fc-491b-b572-0a2fe3ce8917%40googlegroups.com.
>
> For more options, visit https://groups.google.com/d/optout.

Deepesh Maheshwari

unread,
Sep 2, 2014, 2:31:44 AM9/2/14
to mongod...@googlegroups.com
Thanks Asya and False,
Coincidentally, we also came up with same solution with help of some operations as suggested by False.

Deepesh.
Reply all
Reply to author
Forward
0 new messages