MongoDB
 Computer >> コンピューター >  >> プログラミング >> MongoDB

MongoDBで日付ごとにデータをグループ化する方法

MongoDBで日付単位にデータを集計・グループ化したい場合、アグリゲーションフレームワーク(aggregate)を利用するのが最も効果的です。この記事では、実際にコレクションを作成し、日付ごとにログイン回数をグループ化する手順を具体的なコード例とともに解説します。

1. サンプルコレクションの作成

まず、日付情報を含むドキュメントを格納するコレクションを作成します。以下のクエリでは、groupByDateDemoというコレクションに、UserLoginDateTime(ユーザーのログイン日時)フィールドを持つドキュメントを順番に挿入しています。

> db.groupByDateDemo.insertOne({"UserLoginDateTime":new ISODate()});
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5c6ee4df6fd07954a4890695")
}
> db.groupByDateDemo.insertOne({"UserLoginDateTime":new ISODate("2019-01-31 15:20:09.234Z")});
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5c6ee51c6fd07954a4890696")
}
> db.groupByDateDemo.insertOne({"UserLoginDateTime":new ISODate("2017-04-21 16:12:13.240Z")});
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5c6ee5336fd07954a4890697")
}
> db.groupByDateDemo.insertOne({"UserLoginDateTime":new ISODate("2016-05-25 19:11:21.130Z")});
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5c6ee54b6fd07954a4890698")
}
> db.groupByDateDemo.insertOne({"UserLoginDateTime":new ISODate("2016-05-25 19:11:21.130Z")});
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5c6ee8de6fd07954a4890699")
}
> db.groupByDateDemo.insertOne({"UserLoginDateTime":new ISODate()});
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5c6ee8e76fd07954a489069a")
}

2. 登録されたドキュメントの確認

find()メソッドを使うと、コレクション内のすべてのドキュメントを表示できます。ここでは出力を見やすくするためにpretty()を組み合わせています。

> db.groupByDateDemo.find().pretty();

実行結果は以下のとおりです。同じ日時のドキュメントが2件存在することに注目してください。

{
   "_id" : ObjectId("5c6ee4df6fd07954a4890695"),
   "UserLoginDateTime" : ISODate("2019-02-21T17:50:23.076Z")
}
{
   "_id" : ObjectId("5c6ee51c6fd07954a4890696"),
   "UserLoginDateTime" : ISODate("2019-01-31T15:20:09.234Z")
}
{
   "_id" : ObjectId("5c6ee5336fd07954a4890697"),
   "UserLoginDateTime" : ISODate("2017-04-21T16:12:13.240Z")
}
{
   "_id" : ObjectId("5c6ee54b6fd07954a4890698"),
   "UserLoginDateTime" : ISODate("2016-05-25T19:11:21.130Z")
}
{
   "_id" : ObjectId("5c6ee8de6fd07954a4890699"),
   "UserLoginDateTime" : ISODate("2016-05-25T19:11:21.130Z")
}
{
   "_id" : ObjectId("5c6ee8e76fd07954a489069a"),
   "UserLoginDateTime" : ISODate("2019-02-21T18:07:35.208Z")
}

3. 日付でグループ化するアグリゲーションクエリ

それでは、MongoDBで日付ごとにグループ化を行うクエリを見ていきましょう。このクエリのポイントは以下の通りです。

  • $year と $dayOfYear:日時から「年」と「年内の通算日」を抽出し、年をまたぐデータでも正しく日単位でグループ化できるようにします。
  • $multiply:年に400を掛けることで、異なる年の同じ日を区別できるようにしています。
  • $sum:同じ日付の出現回数(ログイン回数)をカウントします。
  • $min:グループ内の最小の日時を代表値として取得します。
  • $sort / $limit / $project:結果を日付順に並べ替え、上位10件に絞り込み、出力フィールドを整形します。
> db.groupByDateDemo.aggregate([
... { $group: {
... _id: {
... $add: [
... { $dayOfYear: "$UserLoginDateTime"},
... { $multiply:
... [400, {$year: "$UserLoginDateTime"}]
... }
... ]},
... NumberOfTimes: { $sum: 1 },
... f: {$min: "$UserLoginDateTime"}
... }
... },
... { $sort: {_id: 1} },
... { $limit: 10 },
... { $project: { date: "$f", NumberOfTimes: 1, _id: 0} }
... ]);

4. 実行結果

クエリを実行すると、以下のように日付ごとにグループ化された結果が得られます。NumberOfTimesがその日の出現回数、dateが該当する日時を表します。

{ "NumberOfTimes" : 2, "date" : ISODate("2016-05-25T19:11:21.130Z") }
{ "NumberOfTimes" : 1, "date" : ISODate("2017-04-21T16:12:13.240Z") }
{ "NumberOfTimes" : 1, "date" : ISODate("2019-01-31T15:20:09.234Z") }
{ "NumberOfTimes" : 2, "date" : ISODate("2019-02-21T17:50:23.076Z") }

まとめ

MongoDBで日付ごとにデータをグループ化するには、アグリゲーションフレームワークの$groupステージと日付演算子($year$dayOfYearなど)を組み合わせるのが基本のアプローチです。今回の例のように、年と通算日を組み合わせたキーを作成することで、年をまたぐデータでも正確に日単位の集計が可能になります。アクセスログの分析やユーザー行動の集計など、さまざまな場面で応用できるテクニックなので、ぜひ活用してみてください。

  1. 【MongoDB】集計パイプラインの$groupを使って日付ごとにデータをグループ化する方法

    MongoDBで日付ごとにドキュメントをグループ化したい場合は、aggregate()メソッド内で$group演算子を使用します。本記事では、サンプルコードを交えながら、コレクションの作成から日付単位でのグループ化までの一連の手順をわかりやすく解説します。1. サンプルコレクションの作成まず、日付情報を含むドキュメントを格納するコレクションを用意しましょう。以下の例では、db.demo657というコレクションに対して、id、Name、DueDate(ISODate形式)の各フィールドを持つドキュメントを、insertOne()メソッドで3件挿入しています。> db.demo657.ins

  2. MongoDBのaggregateで$groupを使って複数の集計結果を一度に取得する方法

    MongoDBでは、$facetと$groupを組み合わせることで、1回のaggregateクエリで複数の集計結果を同時に取得できます。この記事では、実際のコード例を通じてその方法を解説します。サンプルコレクションの作成まず、ドキュメントを含むコレクションを作成しましょう。以下のようにinsertOne()メソッドを使ってデータを挿入します。> db.demo765.insertOne( ... { ... Name:John, ... Category:ComputerScience, ... SubjectName:MongoDB,