1

I have following documents in product collection.

db.product.find()
{ "_id" : 1, "results" : [ { "product" : "abc", "score" : 10 }, { "product" : "xyz", "score" : 5 } ] }
{ "_id" : 2, "results" : [ { "product" : "abc", "score" : 8 }, { "product" : "xyz", "score" : 7 } ] }
{ "_id" : 3, "results" : [ { "product" : "abc", "score" : 7 }, { "product" : "xyz", "score" : 8 } ] }

The following query returns the result as expected with elemMatch.

> db.product.find(  {  results :  { $elemMatch :   { product : "xyz" , score : { $eq : 5}  }  } }   )
{ "_id" : 1, "results" : [ { "product" : "abc", "score" : 10 }, { "product" : "xyz", "score" : 5 } ] }

Similarly this also returns the expected results.

> db.product.find(  {  results :  {    product : "xyz" , score : 5  }   }   )
{ "_id" : 1, "results" : [ { "product" : "abc", "score" : 10 }, { "product" : "xyz", "score" : 5 } ] }

But when I use comparison operator inside an array, I am not getting any results.

db.product.find(  {  results :  {    product : "xyz" , score : { $eq : 5}  }   }   )

I am unable to figure out this unexpected behavior.

Shiko
  • 2,448
  • 1
  • 24
  • 31
Girish Gupta
  • 1,241
  • 13
  • 27

2 Answers2

2

There are two ways to make queries: passing subdocuments and using dot notation.

To query for nested fields you should use dot notation. This means you need to do:

db.test.find({"results.product": "xyz", "results.score": {$eq : 5}})

If you pass a subdocument as you do, then mongoDB do the exact match. This means there should not be any additional properties and basically in your case it expects score to be {"$eq" : 5} (literally have property named $eq)

For more info please check out this answer and documentation.

Community
  • 1
  • 1
Antonio Narkevich
  • 4,206
  • 18
  • 28
0

I have run the explain for all 4 commands. Here are the filters that mongoDB is creating internally:

db.product.find({ results : { product : "xyz" , score : 5  }   }).explain()
"filter" : {
                "results" : {
                    "$eq" : {
                        "product" : "xyz",
                        "score" : 5
                    }
                }
            }


db.product.find({ "results.product" : "xyz" , "results.score" : 5   }).explain()
      "filter" : {
                    "$and" : [
                        {
                            "results.product" : {
                                "$eq" : "xyz"
                            }
                        },
                        {
                            "results.score" : {
                                "$eq" : 5
                            }
                        }
                    ]
                }

db.product.find(  {  results :  { $elemMatch :   { product : "xyz" , score : { $eq : 5}  }  } }   ).explain()
          "filter" : {
                        "results" : {
                            "$elemMatch" : {
                                "$and" : [
                                    {
                                        "product" : {
                                            "$eq" : "xyz"
                                        }
                                    },
                                    {
                                        "score" : {
                                            "$eq" : 5
                                        }
                                    }
                                ]
                            }
                  }
                }

db.product.find(  {  results :  {    product : "xyz" , score : { $eq : 5}  }   }   ).explain()

                    "filter" : {
                                "results" : {
                                    "$eq" : {
                                        "product" : "xyz",
                                        "score" : {
                                            "$eq" : 5
                                        }
                                    }
                                }
                            }
Girish Gupta
  • 1,241
  • 13
  • 27