Brett
Brett

Reputation: 12007

MongoDB - How can I use $elemMatch with multiple criteria

I have a MongoDB record that has the following record structure.

{
    "_id" : ObjectId("547e29f2421aa9302705679a"),
    "runs" : [ 
        {
            "datetime" : "2014-04-2813:18:54.959579",
            "tag" : "v1.0",
        }, 
        {
            "datetime" : "2014-11-1122:45:13.841787",
            "tag" : "v1.1",
        }
    ],
    "person1" : "person1_id",
    "person2" : "person2_id"
}

Some of my records will have more or less runs , each with a different tag. I am trying to formulate a query that will tell me which records have a run with tag=v1.1 but not a run with tag=v1.0.

I am just beginning to learn MongoDB, but I've come up with the query:

db.mycollection.find( { $and: [
  { runs : { $elemMatch : { tag : 'v1.1' } } },
  { runs : { $elemMatch : { $ne: { tag : 'v1.0' } } } },
]})

however, this still returns records with tag=v1.0. I'm not sure where I'm going wrong here. Can anyone point me in the correct direction?

Upvotes: 1

Views: 517

Answers (2)

BatScream
BatScream

Reputation: 19700

You don't need a $elemMatch there, and can fire a direct count(). Use $elemMatch only if you want to update or project an array element.

db.mycollection.count({$and:[{"runs.tag":"v1.1"},
                    {"runs.tag":{$not:{"$eq":"v1.0"}}}]})

or a find()

db.mycollection.find({$and:[{"runs.tag":"v1.1"},
                    {"runs.tag":{$not:{"$eq":"v1.0"}}}]})

Upvotes: 1

Brett
Brett

Reputation: 12007

I found using the $not in the correct place does the trick.

db.mycollection.find( { $and: [
  { runs : { $elemMatch : { tag : 'v1.1' } } },
  { runs : { $not: { $elemMatch : { tag : 'v1.0' } } } },
]}).count()

Upvotes: 1

Related Questions