Reputation: 163
My MongoDB data structure looks like this:
{
users: [{
userref: "User1",
results: [{
testref: "TEST1",
history: [{
score: 10
}, {
score: 15
}]
}, {
testref: "TEST2",
history: [{
score: 2
}, {
score: 1
}]
}]
}]
}
I have a collection of users, each with an array of results (one result object for each test), and within each result, an array of the history of the historical scores.
What I need to do is "return the userref for all users whose most recent score for TEST1 is X and whose most recent score for TEST2 is Y". Users who have not completed one or other of these tests should not be returned. By "most recent", I mean the last in the array.
I'm assuming I need to use aggregation, but I'm totally new to this, so could do with some help.
This is what I have tried so far, and it works, but it only matches the condition where TEST1=15, and I would also like it to match the condition TEST2=1.
[{$unwind: {
path: '$results’,
preserveNullAndEmptyArrays: false
}}, {$match: {
'results.testref': 'TEST1'
}}, {$project: {
results: 1,
userref: 1,
}}, {$replaceRoot: {
newRoot: {
$mergeObjects: [
{
userref: '$userref'
},
'$results'
]
}
}}, {$project: {
userref: 1,
history: {
$slice: [
'$history',
-1
]
}
}}, {$match: {
'history.score': 15
}}, {$project: {
userref: 1,
}}]
Thanks
Upvotes: 0
Views: 79
Reputation: 22974
To match both the conditions,
db.getCollection('test2').aggregate([{"$unwind":"$users"}, {$unwind:"$users.results"},
{$project:
{"lastScore":
{$slice:
["$users.results.history", -1]
},
"users.userref":1,
"users.results.testref":1
}
},
{
$match:{"$or":[{
$and:[
{"users.results.testref":"TEST1"},
{"lastScore.0.score":15}
]},
{
$and:[
{"users.results.testref":"TEST2"},
{"lastScore.0.score":1}
]}
]
}
},
{
$group:{
"_id":{"_id":"$_id","userref":"$users.userref"},
"data":{$push:{"tests":"$users.results.testref", "userref":"$users.userref"}}
}
},
{
$project:{
"_id":1,
"validUser":{
"$filter":{
"input":"$data",
"as":"data",
"cond":{$or:[{$eq:["$$data.tests","TEST1"]}, {$eq:["$$data.tests","TEST2"]}]}
}}
}
},
{
$project:{
"_id.userref":1
}
}
])
What does the query do:
Output:
/* 1 */
{
"_id" : {
"userref" : "User1"
}
}
Upvotes: 1