MongoDBの集計パイプラインでコレクション内ドキュメントの1日あたり平均件数を取得する方法
記録されたドキュメントの1日あたりの平均件数を取得するには、MongoDBのaggregate()メソッドを使用します。集計パイプラインの中で$match、$group、$projectを組み合わせることで、期間全体の合計値を経過日数で割り、1日あたりの平均値を算出できます。
まずはサンプルデータを作成するところから見ていきましょう。
サンプルコレクションの作成
以下のようにinsertOne()を使って、日付(DueDate)と数値(Value)を持つドキュメントを3件登録します。
> db.demo451.insertOne({
... DueDate:new ISODate("2020-03-15T10:50:35.000Z"),
... Value: 10
... }
... );
{
"acknowledged" : true,
"insertedId" : ObjectId("5e7b5c5d71f552a0ebb0a6e9")
}
> db.demo451.insertOne({
... DueDate:new ISODate("2020-03-14T10:50:35.000Z"),
... Value: 10
... }
... );
{
"acknowledged" : true,
"insertedId" : ObjectId("5e7b5c5d71f552a0ebb0a6ea")
}
> db.demo451.insertOne({
... DueDate:new ISODate("2020-03-13T10:50:35.000Z"),
... Value: 10
... }
... );
{
"acknowledged" : true,
"insertedId" : ObjectId("5e7b5c5d71f552a0ebb0a6eb")
}登録したドキュメントの確認
find()メソッドを使うと、コレクション内のすべてのドキュメントを表示できます。
> db.demo451.find();
実行すると、次のような出力が得られます。
{ "_id" : ObjectId("5e7b5c5d71f552a0ebb0a6e9"), "DueDate" : ISODate("2020-03-15T10:50:35Z"), "Value" : 10 }
{ "_id" : ObjectId("5e7b5c5d71f552a0ebb0a6ea"), "DueDate" : ISODate("2020-03-14T10:50:35Z"), "Value" : 10 }
{ "_id" : ObjectId("5e7b5c5d71f552a0ebb0a6eb"), "DueDate" : ISODate("2020-03-13T10:50:35Z"), "Value" : 10 }1日あたりの平均件数を求めるクエリ
それでは、コレクションに記録されたドキュメントの1日あたり平均件数を取得するクエリを見てみましょう。処理の流れは以下の3段階です。
- $match: 現在の日時より前のドキュメントだけを抽出します。
- $group: 最も古い日付(olderDate)とValueの合計(sumValue)を計算します。
- $project: 合計値を「現在日時から最古日付までの経過日数」で割り、1日あたりの平均値を求めます。
> db.demo451.aggregate({
... $match: {
... DueDate: {
... $lt: new ISODate()
... }
... }
... }, {
... $group: {
... _id: null,
... olderDate: {
... $min: "$DueDate"
... },
... sumValue: {
... $sum: "$Value"
... }
... }
... }, {
... $project: {
... _id: 0,
... averageValue: {
... $divide: ["$sumValue", {
... $divide: [{
... $subtract: [new ISODate(), "$olderDate"]
... }, 1000 * 60 * 60 * 24]
... }]
... }
... }
... })実行結果
このクエリを実行すると、次のような出力が得られます。
{ "averageValue" : 2.475558456547562 }ポイント解説
このクエリの核となるのは、$subtractで現在日時と最古のDueDateの差分(ミリ秒)を計算し、それを 1000 * 60 * 60 * 24(1日分のミリ秒)で割って経過日数に変換している部分です。さらに$divideでValueの合計をこの経過日数で割ることで、1日あたりの平均値が算出されます。
なお、日付の差分計算ではタイムゾーンや時刻の端数の影響を受けるため、厳密な「暦日ベース」の平均が必要な場合は、$dateToStringなどで日付を丸めてからグループ化する方法も検討するとよいでしょう。
-
MongoDBでコレクション内のドキュメント数を制限する方法(Capped Collectionの使い方)
MongoDBでコレクション内のドキュメント数を制限するには?MongoDBのコレクションに保存できるドキュメントの数を制限したい場合は、「capped: true」を指定してCapped Collection(キャップドコレクション)を作成します。作成時にsize(最大サイズ)やmax(最大ドキュメント数)を設定することで、コレクションの容量と件数の上限を定義できます。Capped CollectionとはCapped Collectionは、挿入順にドキュメントを保持し、上限に達すると最も古いドキュメントから自動的に削除される固定サイズのコレクションです。ログデータやキャッシュなど、最新の
-
MongoDB集計パイプラインで重複するNameフィールド値ごとの出現回数を取得する方法
MongoDBでは、$unwindと$groupを組み合わせた集計(アグリゲーション)パイプラインを使うことで、配列内に存在する重複したフィールド値を名前ごとにグループ化し、それぞれの出現回数を簡単に取得できます。ここでは、具体的な例をもとにその手順を解説します。サンプルコレクションの作成まずは、ドキュメントを含むコレクションを作成してみましょう。以下の例では、demo558というコレクションに、国コードと複数人の受講科目情報を持つドキュメントを挿入します。> db.demo558.insertOne( ... { ... _id : 100, ... CountryCode