sql >> Database >  >> NoSQL >> MongoDB

Vind laatste record van elke dag

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" }
    }}
])


  1. Hoe krijg ik gekleurde query-uitvoer en shell in MongoDB?

  2. Python redis abonneren kan niet alle gegevens krijgen?

  3. S3 gebruiken als database versus database (bijv. MongoDB)

  4. Socket.io-gebruikers tellen op horizontale servers