sql >> Databáze >  >> NoSQL >> MongoDB

Najděte poslední záznam každého dne

Trochu modernější než původní odpověď:

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

Platí stejný princip, že v podstatě $sort kolekce a poté $group na požadovaném seskupovacím klíči vyzvednutím $last data z hranice seskupení.

Od původního psaní je to trochu jasnější, že můžete použít $$ROOT místo určení každé vlastnosti dokumentu a samozřejmě $replaceRoot fáze umožňuje obnovit tato data plně jako původní formulář dokumentu.

Ale obecné řešení je stále $sort nejprve, pak $group na společném klíči, který je vyžadován, a ponechte $last nebo $first v závislosti na výskytech pořadí řazení z hranice seskupení pro vlastnosti, které jsou vyžadovány.

Také pro data BSON, na rozdíl od hodnoty časového razítka jako v otázce, viz Výsledek skupiny podle 15minutového časového intervalu v MongoDb pro různé přístupy, jak akumulovat pro různé časové intervaly ve skutečnosti pomocí a vracející hodnoty BSON Date.

Nejste si úplně jisti, k čemu zde jdete, ale můžete to udělat souhrnně, pokud to chápu správně. Chcete-li získat poslední záznam pro každý den:

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

Princip je tedy takový, že s ohledem na hodnotu časového razítka proveďte výpočet data, abyste jej promítli jako půlnoční čas na začátku každého dne. Poté jako _id klíč na dokumentu je již monotónní (vždy se zvyšuje), poté jednoduše seskupte wholeDay hodnotu při vytažení $last dokument z hranice seskupení.

Pokud nepotřebujete všechna pole, promítněte a seskupte pouze ta, která chcete.

A ano, můžete to udělat v rámci jarních dat. Jsem si jistý, že tam je zabalený příkaz. Ale jinak zaklínadlo pro získání nativního příkazu vypadá asi takto:

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

Pro záznam, pokud jste ve skutečnosti měli typ data BSON místo čísla jako časové razítko, můžete přeskočit matematiku data:

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


  1. Chyba ServerSelectionTimeoutError při připojování k aws pomocí pymongo

  2. Má MongoDB nativní rozhraní REST?

  3. NodeJS Mongo - Mongoose - Dynamický název kolekce

  4. shell skript - zkontrolujte, zda běží mongod server