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

Skupinový výsledek podle časového intervalu 15 minut v MongoDb

Existuje několik způsobů, jak to udělat.

První je s operátory agregace data, které vám umožňují rozebrat hodnoty „datum“ v dokumentech. Konkrétně pro „seskupení“ jako primární záměr:

db.collection.aggregate([
  { "$group": {
    "_id": {
      "year": { "$year": "$created_at" },
      "dayOfYear": { "$dayOfYear": "$created_at" },
      "hour": { "$hour": "$created_at" },
      "interval": {
        "$subtract": [ 
          { "$minute": "$created_at" },
          { "$mod": [{ "$minute": "$created_at"}, 15] }
        ]
      }
    }},
    "count": { "$sum": 1 }
  }}
])

Druhým způsobem je použití malého triku, když se objekt data odečte (nebo jiná přímá matematická operace) od jiného objektu data, výsledkem je pak číselná hodnota představující časové razítko epochy v milisekundách mezi těmito dvěma objekty. Takže pouhým použitím data epochy získáte reprezentaci epochy v milisekundách. Potom pro interval použijte datovou matematiku:

db.collection.aggregate([
    { "$group": {
        "_id": {
            "$subtract": [
                { "$subtract": [ "$created_at", new Date("1970-01-01") ] },
                { "$mod": [ 
                    { "$subtract": [ "$created_at", new Date("1970-01-01") ] },
                    1000 * 60 * 15
                ]}
            ]
        },
        "count": { "$sum": 1 }
    }}
])

Záleží tedy na tom, jaký výstupní formát chcete pro interval seskupování. Oba v podstatě představují totéž a mají dostatek dat k tomu, aby je bylo možné ve vašem kódu znovu sestavit jako objekt „datum“.

Do části „operátor seskupení“ za seskupení _id můžete vložit cokoli jiného, ​​co chcete . Pouze používám základní příklad "počítání" namísto jakéhokoli skutečného prohlášení od vás, co opravdu chcete dělat.

MongoDB 4.xa vyšší

Od původního napsání byly některé dodatky k operátorům agregace dat, ale od MongoDB 4.0 bude skutečné „skutečné odlévání typů“ na rozdíl od základních matematických triků, které zde provádíme s konverzí data BSON.

Můžeme například použít $toLong a $toDate jako noví pomocníci zde:

db.collection.aggregate([
  { "$group": {
    "_id": {
      "$toDate": {
        "$subtract": [
          { "$toLong": "$created_at" },
          { "$mod": [ { "$toLong": "$created_at" }, 1000 * 60 * 15 ] }
        ]
      }
    },
    "count": { "$sum": 1 }
  }}
])

To je o něco kratší a nevyžaduje definování externího data BSON pro hodnotu „epoch“ jako konstantu při definování kanálu, takže je to docela konzistentní pro všechny jazykové implementace.

To jsou jen dvě z "pomocných" metod pro převod typů, které jsou všechny navázány na $convert metoda, což je "delší" forma implementace umožňující vlastní manipulaci na null nebo chyba při převodu.

S takovým castingem je dokonce možné získat Date informace z ObjectId primárního klíče, protože by to byl spolehlivý zdroj data „vytvoření“:

db.collection.aggregate([
  { "$group": {
    "_id": {
      "$toDate": {
        "$subtract": [
          { "$toLong": { "$toDate": "$_id" }  },
          { "$mod": [ { "$toLong": { "$toDate": "$_id" } }, 1000 * 60 * 15 ] }
        ]
      }
    },
    "count": { "$sum": 1 }
  }}
])

Takže "casting typů" s tímto druhem konverze může být docela mocným nástrojem.

Upozornění - ObjectId hodnoty jsou omezeny na přesnost na sekundu pouze pro hodnotu interního času, která tvoří část jejich dat umožňující $toDate konverze. Skutečný vložený „čas“ s největší pravděpodobností závisí na používaném ovladači. Kde přesnost je vyžadováno, přesto se doporučuje použít diskrétní pole Datum BSON namísto spoléhání se na ObjectId hodnoty.



  1. Příkaz Redis pro získání všech dostupných klíčů?

  2. Co je to TransientTransactionError v Mongoose (nebo MongoDB)?

  3. Proč potřebujeme, jaké výhody používat mangustu

  4. Dynamické klíče po $group by