Een beetje moderner dan het oorspronkelijke antwoord:
db.collection.aggregate([
{ "$sort": { "date": 1 } },
{ "$group": {
"_id": {
"$subtract": ["$date",{"$mod": ["$date",86400000]}]
},
"doc": { "$last": "$$ROOT" }
}},
{ "$replaceRoot": { "newDocument": "$doc" } }
])
Hetzelfde principe is van toepassing dat u in wezen $sort
de verzameling en vervolgens $group
op de vereiste groeperingssleutel het ophalen van de $last
gegevens van de groeperingsgrens.
De dingen een beetje duidelijker maken, omdat het originele schrijven is dat je $$ROOT
. kunt gebruiken in plaats van elke documenteigenschap op te geven, en natuurlijk de $replaceRoot
stage kunt u die gegevens volledig herstellen als de originele documentvorm.
Maar de algemene oplossing is nog steeds $sort
eerst, dan $group
op de gemeenschappelijke sleutel die vereist is en bewaar de $last
of $first
afhankelijk van de sorteervolgorde die voorkomt vanaf de groeperingsgrens voor de eigenschappen die vereist zijn.
Ook voor BSON-datums in tegenstelling tot een tijdstempelwaarde zoals in de vraag, zie Groepsresultaat met een tijdsinterval van 15 minuten in MongoDb voor verschillende benaderingen van hoe te accumuleren voor verschillende tijdsintervallen die daadwerkelijk BSON-datumwaarden gebruiken en retourneren.
Niet helemaal zeker wat je hier voor gaat, maar je zou dit in totaal kunnen doen als ik het goed begrijp. Dus om het laatste record voor elke dag te krijgen:
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" },
}}
])
Dus het principe hier is dat, gezien de tijdstempelwaarde, de datumberekening moet worden uitgevoerd om dat als de middernachttijd aan het begin van elke dag te projecteren. Dan als de _id
toets op het document is al monotoon (altijd toenemend), groepeer dan gewoon op de wholeDay
waarde tijdens het trekken van de $last
document van de groeperingsgrens.
Als je niet alle velden nodig hebt, projecteer en groepeer dan alleen de velden die je wilt.
En ja, dat kan in het voorjaarsdataframework. Ik weet zeker dat er een ingepakt commando in zit. Maar anders gaat de bezwering om naar het oorspronkelijke commando te gaan ongeveer als volgt:
mongoOps.getCollection("yourCollection").aggregate( ... )
Voor de goede orde, als je BSON-datumtypes had in plaats van een tijdstempel als nummer, dan kun je de datumberekening overslaan:
db.collection.aggregate([
{ "$group": {
"_id": {
"year": { "$year": "$date" },
"month": { "$month": "$date" },
"day": { "$dayOfMonth": "$date" }
},
"hchp": { "$last": "$hchp" }
}}
])