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 naObjectId
hodnoty.