Monday, 1 July 2019

Importance Of Using $elemMatch Operator, While Working With Arrays In MongoDB.

In MongoDB, its a common scenario, where we need to filter out the documents, based on the sub document/arrays, but there are couple of ways in which we can query the documents with arrays. It purely depends on the developer use case.

1. Using the dot operator. (like:  comments.rating).
2. Using the $elemMatch operator.

The main difference is that, they both behave differently when using with multiple conditions in filter operation. This blog is mainly to showcase that difference, and how they work when using it with array.

Lets understand this by example:

Suppose, we have a restaurant collection, with a document as follows: It has a comments array, with customer rating, and customer category (Bronze/Gold).

{
    "name": "Fly High",
    "restaurant_id" : "30075444"
    "street" : "Baner",
    "zipcode" : "10462"
    "comments" : [
        {
            "rating" : "3",
            "message":"Nice Ambience Only",
            "customer":  "Gold"
        },
        {
            "rating" : "3.5",
            "message":"Ok Food",
            "customer":"Bronze"
        },
        {
            "rating" : "5", 
            "message":"Nice Ambience & Food",
            "customer":  "Bronze"
        }, 
        {
            "rating" : "2",
            "message":"Bad Service",
            "customer":  "Gold"
        }
    ]
}

This is just the single restaurant, suppose if we have information for multiple restaurants (documents), and if we need to find out, all those restaurants, who have been rated greater than 4, by Gold customer.

Lets evaluate both the supported ways, for querying the document with arrays.

1. Using the (.) dot operator :

Query Statement  :  Find all restaurants, who have been rated greater than 4, by "gold" customer.

Query :  db.restaurant.find({"comments.rating":{$gt:4}, "comments.customer":"gold"})

Suppose, if we only have the above specified document in the collection, and we executed the above query, the result count should be 0, as we don;t have any document, where the gold customer has given rating greater than 4. But the inverse of this, we will get the above document in result.

As, we can see in the above document, only rating greater than 4 we have, is from "Bronze" customer, still we get the current document in the result.

So, how "." dot operator works in multiple condition is, it will check, whether any combination of these condition matches in the comments array, if it has found the match, it will return that document.

In the current query case :

1. It will check, whether we do have any rating greater that 4 ? (Yes, we do have from the bronze customer).
2. It will check, whether we have any "gold" customer comment ? (Yes, we do have multiple comments).

i.e combination of conditions are matched in the array, lets return that document.

Note: It is good, when we are doing "OR" matching, but for "AND" matching, it can return some unexpected results.

The alternate for this, using the "$elemMatch" operator, which will behave as expected.


2. Using the ($elemMatch) operator : 

Lets rewrite the same above query using the "$elemMatch" operator and validate the results.

Query Statement  :  Find all restaurants, who have been rated greater than 4, by "gold" customer.

Query :

db.restaurant.find({"comments":{$elemMatch:{"rating":{$gt:4},"customer":"gold"}}})

If we only have the above document in collection, and we execute the elemMatch query, it will return the result count as 0. As, no document exist, where "gold" customer has given the rating greater than 5, and that was the expected result.

Hope it will help you, in understanding the difference between, in both the operators. The dot operator still can be used, when we do have only single condition in query.


3 comments:

  1. Nice, helpful for fresh learning as well as for quick revise...

    ReplyDelete
  2. NJ Casino Review - Jetblue Casino
    JetBlue Casino has everything you'd need to play. From slots to table games, 진주 출장안마 you'll find great promotions, 김제 출장안마 generous bonuses and 태백 출장안마 a 정읍 출장샵 variety of 군포 출장안마

    ReplyDelete
  3. And this is the main cause for the existence of so many no deposit casinos in the marketplace - they search to expand their participant swimming pools by offering their clients free money. Be ready for withdrawal limits if you claim no deposit bonuses or free spins. These types of on line casino bonuses prohibit how a lot you can to|you probably can} withdraw outcome of|as a outcome of} you’ve claimed a bonus before depositing any of your own money. The finest on-line casinos for Arabian players help you celebrate your birthday in style. In most 메리트카지노 circumstances, you will receive an e-mail wishing you a contented birthday on the date you entered during the registration process. This e-mail will comprise a special present, typically an exclusive reload bonus or free spins.

    ReplyDelete