Consider the following mongo collection "events":
{ "_id" : ObjectId("512bc95fe835e68f199c8686"), userId: 1, type: "music" eventNum: 1 }
{ "_id" : ObjectId("512bc962e835e68f199c8687"), userId: 1, type: "music" eventNum: 2 }
{ "_id" : ObjectId("55f5a192d4bede9ac365b257"), userId: 2, type: "music" eventNum: 3 }
{ "_id" : ObjectId("55f5a192d4bede9ac365b258"), userId: 2, type: "music" eventNum: 4 }
{ "_id" : ObjectId("55f5a1d3d4bede9ac365b259"), userId: 1, type: "music" eventNum: 5 }
{ "_id" : ObjectId("55f5a1d3d4bede9ac365b25a"), userId: 1, type: "athletic" eventNum: 6 }
{ "_id" : ObjectId("55f5a1d3d4bede9ac365b25b"), userId: 2, type: "athletic" eventNum: 7 }
Each event is created with a userId, a type and an eventNum. I need to find the top 3 events of userId: 1. So I run this query:
db.getCollection('events').aggregate([
{
"$match": {
"userId": 1
}
},
{
"$sort": { "eventNum": 1 }
},
{
"$limit": 3
}
])
Which returns the dataset (NOTE there are no "athletic" events returned):
{ "_id" : ObjectId("512bc95fe835e68f199c8686"), userId: 1, type: "music" eventNum: 1 }
{ "_id" : ObjectId("512bc962e835e68f199c8687"), userId: 1, type: "music" eventNum: 2 }
{ "_id" : ObjectId("55f5a1d3d4bede9ac365b259"), userId: 1, type: "music" eventNum: 5 }
Now, however, I want all "athletic" events of userId: 1, but ONLY if they are in the top 3. Since there are no "athletic" events in the top 3, we would expect the following query to return no documents:
db.getCollection('events').aggregate([
{
"$match": {
"userId": 1
}
},
{
"$sort": { "eventTime": 1 }
},
{
"$limit": 3
},
{
"$match": {
"type": "athletic"
}
}
])
HOWEVER, this query actually returns this dataset:
{ "_id" : ObjectId("55f5a1d3d4bede9ac365b25a"), userId: 1, type: "athletic" eventNum: 6 }
Can someone explain what is going on here? It seems that the sort/limit is happening after the second match. Is there anyway to get around this without making multiple queries?
$matchcondition if you think otherwise. - Neil Lunn