sql >> Database teknologi >  >> NoSQL >> MongoDB

Find sidste rekord for hver dag

Lidt mere moderne end det originale svar:

db.collection.aggregate([
  { "$sort": { "date": 1 } },
  { "$group": {
    "_id": {
      "$subtract": ["$date",{"$mod": ["$date",86400000]}]
    },
    "doc": { "$last": "$$ROOT" }
  }},
  { "$replaceRoot": { "newDocument": "$doc" } }
])

Det samme princip gælder, at du i det væsentlige $sort samlingen og derefter $group på den påkrævede grupperingsnøgle ved at hente $last data fra grupperingsgrænsen.

Gør tingene lidt klarere, da den oprindelige skrivning er, at du kan bruge $$ROOT i stedet for at specificere hver dokumentegenskab, og selvfølgelig $replaceRoot fase giver dig mulighed for at gendanne disse data fuldt ud som den originale dokumentformular.

Men den generelle løsning er stadig $sort først, derefter $group på den fælles nøgle, der kræves, og behold $last eller $first afhængigt af sorteringsrækkefølge-forekomster fra grupperingsgrænsen for de egenskaber, der kræves.

Se også for BSON-datoer i modsætning til en tidsstempelværdi som i spørgsmålet Grupper resultat efter 15 minutters tidsinterval i MongoDb for forskellige tilgange til, hvordan man akkumulerer for forskellige tidsintervaller, der faktisk bruger og returnerer BSON-datoværdier.

Ikke helt sikker på, hvad du går efter her, men du kan gøre dette samlet, hvis jeg forstår det rigtigt. Så for at få den sidste rekord for hver 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å princippet her er, at givet tidsstemplets værdi, skal du regne med datoen for at fremskrive det som midnatstid i begyndelsen af ​​hver dag. Derefter som _id tasten på dokumentet er allerede monoton (altid stigende), så grupper blot på heledagen værdi, mens du trækker $last dokument fra grupperingsgrænsen.

Hvis du ikke har brug for alle felterne, så projektér og grupper kun på dem, du ønsker.

Og ja, det kan du gøre i forårets dataramme. Jeg er sikker på, at der er en indpakket kommando derinde. Men ellers går besværgelsen for at komme til den oprindelige kommando sådan her:

mongoOps.getCollection("yourCollection").aggregate( ... )

For en ordens skyld, hvis du faktisk havde BSON-datotyper i stedet for et tidsstempel som et tal, så kan du springe datomatematikken over:

db.collection.aggregate([
    { "$group": { 
        "_id": { 
            "year": { "$year": "$date" },
            "month": { "$month": "$date" },
            "day": { "$dayOfMonth": "$date" }
        },
        "hchp": { "$last": "$hchp" }
    }}
])


  1. Sorter forespørgselsresultater baseret på beskrivelsesværdi af indlejret underdokument i array Mongoose/Mongodb

  2. Fordele ved MongoDB | Ulemper ved MongoDB

  3. Mongo db aggregering flere betingelser

  4. Mongodb node.js $out med aggregering, der kun virker, hvis der kaldes toArray()