Reputation: 8631
Hi I have the following data structure in mongodb:
{
"_id" : "4087322f-1ad0-4595-935f-b41ef6d87306",
"lastModifiedDate" : ISODate("2016-11-22T20:48:05.904Z"),
"notes" : " I do not like him that much",
"peopleId" : "1121",
"status" : "asses"
}
I wish to query the data such that it will return the latest value for each peopleId which also matches a chosen status. I've been looking into $group however doing the equal status is causing some issue.
I have got as far as grouping the values by peopleId using:
.aggregate([
{$group : {_id : "$peopleId", "allData" : {$push : "$$ROOT"}}},
{$sort : { lastModifiedDate : -1}}
]).pretty()
To give give me these results:
{
"_id" : "1123",
"allData" : [
{
"_id" : "c9d6a6ce-104d-414a-8d89-512e556d7aba",
"lastModifiedDate" : ISODate("2016-11-22T20:55:35.662Z"),
"notes" : "He's in!",
"peopleId" : "1123",
"status" : "done"
},
{
"_id" : "14e522d8-6cae-42ee-ad52-d5cf3cae0c29",
"lastModifiedDate" : ISODate("2016-11-22T20:56:46.128Z"),
"notes" : "He's in!",
"peopleId" : "1123",
"status" : "asses"
}
]
}
{
"_id" : "1121",
"allData" : [
{
"_id" : "d2c3e5da-8696-4dcc-a5cd-1f2657f0192c",
"lastModifiedDate" : ISODate("2016-11-22T20:46:35.097Z"),
"notes" : " I do not like him",
"peopleId" : "1121",
"status" : "pending"
},
{
"_id" : "4087322f-1ad0-4595-935f-b41ef6d87306",
"lastModifiedDate" : ISODate("2016-11-22T20:48:05.904Z"),
"notes" : " I do not like him that much",
"peopleId" : "1121",
"status" : "asses"
},
{
"_id" : "be4fa5bd-da8c-4c1a-9010-6a86afd11dbc",
"lastModifiedDate" : ISODate("2016-11-22T20:49:27.268Z"),
"notes" : "He's in!\nTue Nov 22 12:49:27 PST 2016 He's TF OUT",
"peopleId" : "1121",
"status" : "done"
}
]
}
From this I need to extract the most recent entry based on lastModifiedDate and then check that is matches a given status.
Upvotes: 0
Views: 110
Reputation: 39166
Here are the solutions.
Solution 1:-
If you want all the fields in the collection in the output.
db.collection.aggregate([
{$match : {"status" : "asses"}},
{$sort : {peopleId : 1, lastModifiedDate : -1}},
{$group : {_id : "$peopleId", "allData" : {$push : "$$ROOT"}}},
{$project: {_id :0, allData : {$slice : ["$allData", 0, 1]}}}
]);
Output:-
{
"allData" : [
{
"_id" : ObjectId("5834c004ba41f1f22e600c7f"),
"lastModifiedDate" : ISODate("2016-11-24T20:48:05.904Z"),
"notes" : " I do not like him that much",
"peopleId" : "1",
"status" : "asses"
}
]
}
Solution 2:-
If you don't want all the fields from the collection in the output.
db.collection.aggregate([
{$match : {"status" : "asses"}},
{$sort : {peopleId : 1, lastModifiedDate : -1}},
{$group : {_id : "$peopleId", lastModDate : {$first : "$lastModifiedDate"}}}
])
Output:-
{
"_id" : "1",
"lastModDate" : ISODate("2016-11-24T20:48:05.904Z")
}
Upvotes: 1
Reputation: 2650
i created a collection with following docs
{ "_id" : "4087322f-1ad0-4595-935f-b41ef6d87306", "lastModifiedDate" : ISODate("2016-11-22T20:48:05.904Z"), "notes" : " I do not like him that much",
"peopleId" : "1121", "status" : "asses" }
{ "_id" : "4087322f-1ad0-4595-935f-b41ef6d87305", "lastModifiedDate" : ISODate("2016-10-22T20:48:05.904Z"), "notes" : " I do not like him that much",
"peopleId" : "1121", "status" : "asses" }
{ "_id" : "4087322f-1ad0-4595-935f-b41ef6d87304", "lastModifiedDate" : ISODate("2016-11-21T20:48:05.904Z"), "notes" : " I do not like him that much",
"peopleId" : "1121", "status" : "asses" }
and if i execute the following query
db.mel.find().sort({lastModifiedDate:-1}).limit(1)
it gives me
{ "_id" : "4087322f-1ad0-4595-935f-b41ef6d87306", "lastModifiedDate" : ISODate("2016-11-22T20:48:05.904Z"), "notes" : " I do not like him that much",
"peopleId" : "1121", "status" : "asses" }
which is latest as per the lastmodifeddate.
Upvotes: 0