Lite modernare än originalsvaret:
db.collection.aggregate([
{ "$sort": { "date": 1 } },
{ "$group": {
"_id": {
"$subtract": ["$date",{"$mod": ["$date",86400000]}]
},
"doc": { "$last": "$$ROOT" }
}},
{ "$replaceRoot": { "newDocument": "$doc" } }
])
Samma princip gäller att du i princip $sort
samlingen och sedan $group
på den obligatoriska grupperingsnyckeln och hämta $last
data från grupperingsgränsen.
Gör saker lite tydligare eftersom den ursprungliga skriften är att du kan använda $$ROOT
istället för att specificera varje dokumentegenskap, och naturligtvis $replaceRoot
stadium låter dig återställa dessa data helt som originaldokumentformuläret.
Men den allmänna lösningen är fortfarande $sort
först, sedan $group
på den gemensamma nyckeln som krävs och behåll $last
eller $first
beroende på sorteringsordningsförekomster från grupperingsgränsen för de egenskaper som krävs.
Även för BSON-datum i motsats till ett tidsstämpelvärde som i frågan, se Gruppera resultat med 15 minuters tidsintervall i MongoDb för olika tillvägagångssätt för hur man ackumulerar för olika tidsintervall genom att faktiskt använda och returnera BSON-datumvärden.
Jag är inte helt säker på vad du går för här men du kan göra detta sammantaget om jag förstår rätt. Så för att få det sista rekordet för varje dag:
db.collection.aggregate([
// Sort in date order as ascending
{"$sort": { "date": 1 } },
// Date math converts to whole day
{"$project": {
"adco": 1,
"hchc": 1,
"hchp": 1,
"hhphc": 1,
"ptec": 1,
"iinst": 1,
"papp": 1,
"imax": 1,
"optarif": 1,
"isousc": 1,
"motdetat": 1,
"date": 1,
"wholeDay": {"$subtract": ["$date",{"$mod": ["$date",86400000]}]}
}},
// Group on wholeDay ( _id insertion is monotonic )
{"$group":
"_id": "$wholeDay",
"docId": {"$last": "$_id" },
"adco": {"$last": "$adco" },
"hchc": {"$last": "$hchc" },
"hchp": {"$last": "$hchp" },
"hhphc": {"$last": "$hhphc" },
"ptec": {"$last": "$ptec" },
"iinst": {"$last": "$iinst" },
"papp": {"$last": "$papp" },
"imax": {"$last": "$imax" },
"optarif": {"$last": "$optarif",
"isousc": {"$last": "$isouc" },
"motdetat": {"$last": "$motdetat" },
"date": {"$last": "$date" },
}}
])
Så principen här är att med tanke på tidsstämpelvärdet, gör datummatematiken för att beräkna det som midnattstid i början av varje dag. Sedan som _id
tangenten på dokumentet är redan monoton (alltid ökande), gruppera sedan helt enkelt på heldagen
värde medan du drar $last
dokument från grupperingsgränsen.
Om du inte behöver alla fält, projektera och gruppera bara på de du vill ha.
Och ja, du kan göra detta i vårens dataramverk. Jag är säker på att det finns ett inslaget kommando där. Men annars går besvärjelsen att komma till det ursprungliga kommandot ungefär så här:
mongoOps.getCollection("yourCollection").aggregate( ... )
Om du faktiskt hade BSON-datumtyper snarare än en tidsstämpel som siffra, så kan du hoppa över datummatematiken:
db.collection.aggregate([
{ "$group": {
"_id": {
"year": { "$year": "$date" },
"month": { "$month": "$date" },
"day": { "$dayOfMonth": "$date" }
},
"hchp": { "$last": "$hchp" }
}}
])