Calculus5000
Calculus5000

Reputation: 427

MongoDB: $elemMatch issue

I have a restaurants collection that contains 3772 documents, and I am trying to find all documents that contain an element in the grades array that has a score of 80 < score < 100.

However, I noticed that there's a big discrepancy between the following two queries:

db.restaurants.find(
{"grades":
    {$elemMatch: {score: {$gt: 80}, score: {$lt: 100}}}
}
)

returns all the documents, whereas

db.restaurants.find(
{"grades":
    {$elemMatch: {score: {$gt: 80, $lt: 100}}}
}
)

returns just 3 documents.

From the documentation on $elemMatch, it states

The $elemMatch operator matches documents that contain an array field with at least one element that matches all the specified query criteria.

However, I noticed that the first query (acts like the $and operator) seems perform differently to the second query. Why is there a discrepancy?

Example document:

{
"_id" : ObjectId("57290430139a4a37132ca096"),
"address" : {
    "building" : "345",
    "coord" : [
        -73.9864626,
        40.7266739
    ],
    "street" : "East 6 Street",
    "zipcode" : "10003"
},
"borough" : "Manhattan",
"cuisine" : "Indian",
"grades" : [
    {
        "date" : ISODate("2013-05-30T00:00:00Z"),
        "grade" : "A",
        "score" : 12
    },
    {
        "date" : ISODate("2012-04-06T00:00:00Z"),
        "grade" : "C",
        "score" : 92
    },
    {
        "date" : ISODate("2011-11-03T00:00:00Z"),
        "grade" : "C",
        "score" : 41
    }
],
"restaurant_id" : "40381295"
}

Upvotes: 1

Views: 758

Answers (1)

Philipp
Philipp

Reputation: 69663

The things you pass in MongoDB in one pair of { and } are javascript objects. In a javascript object every key can only have one value.

The expression {score: {$gt: 80}, score: {$lt: 100}} tries to assign two different values to the same key score, so one overwrites the other. The result is interpreted as simply {score: {$lt: 100}}.

Your second query should give you the results you want according to your description.

Upvotes: 2

Related Questions