sql >> Databasteknik >  >> NoSQL >> MongoDB

Hitta sista posten för varje dag

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


  1. Fel:Redis-anslutningen till 127.0.0.1:6379 misslyckades - anslut ECONNREFUSED 127.0.0.1:6379

  2. Kan du inte starta logstash med mongoDB config?

  3. Varför den här uppdateringsfrågan bara uppdaterar en post en gång

  4. MongoDB - Skapa ett förhållande