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

MongoDBで値を重複なく選択(distinct)してカウントするクエリの書き方

MongoDBでは、アグリゲーションフレームワーク(集計パイプライン)を活用することで、配列内の値を重複なく抽出し、それぞれの出現回数をカウントできます。本記事では、insertOne()でサンプルデータを作成し、$unwind$groupなどのステージを組み合わせてdistinct(一意)な値を選択・集計する具体的な手順を解説します。

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

まずは、ドキュメントを挿入してコレクションを作成します。各ドキュメントには「Name」と「Marks」を持つdetails配列が含まれています。

> db.demo586.insertOne(
...     {"details": [
...       {
...          "Name":"Chris",
...          "Marks":71
...       },
...       {
...          "Name":"Chris",
...          "Marks":61
...       },
...       {
...          "Name":"David",
...          "Marks":81
...       }
...
...    ]
... }
... );
{
    "acknowledged" : true,
    "insertedId" : ObjectId("5e9200fefd2d90c177b5bcc7")
}
> db.demo586.insertOne(
... {"details": [
...    {
...       "Name":"Chris",
...       "Marks":71
...    },
...    {
...       "Name":"Carol",
...       "Marks":61
...    },
...    {
...       "Name":"David",
...       "Marks":81
...    }
...
... ]
... }
... );
{
    "acknowledged" : true,
    "insertedId" : ObjectId("5e9200fefd2d90c177b5bcc8")
}

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

挿入したすべてのドキュメントは、find()メソッドを使って確認できます。

> db.demo586.find();

上記のクエリを実行すると、次のような出力が得られます。

{ "_id" : ObjectId("5e9200fefd2d90c177b5bcc7"), "details" : [
    { "Name" : "Chris", "Marks" : 71 },
    { "Name" : "Chris", "Marks" : 61 },
    { "Name" : "David", "Marks" : 81 }
] }
{ "_id" : ObjectId("5e9200fefd2d90c177b5bcc8"), "details" : [
    { "Name" : "Chris", "Marks" : 71 },
    { "Name" : "Carol", "Marks" : 61 },
    { "Name" : "David", "Marks" : 81 }
] }

3. distinctに選択してカウントする集計クエリ

続いて、名前ごとに点数を重複なく抽出し、その出現回数をカウントするためのアグリゲーションクエリを見ていきましょう。変数qにパイプラインを定義し、aggregate()メソッドに渡します。

> var q= [
...    { "$unwind": "$details" },
...    {
...       "$group": {
...          "_id": {
...             "Name": "$details.Name",
...             "Marks": "$details.Marks"
...          },
...          "count": { "$sum": 1 }
...       }
...    },
...    {
...       "$group": {
...          "_id": "$_id.Name",
...          "distinctV": {
...             "$addToSet": {
...                "value": "$_id.Marks",
...                "numberOfValues": "$count"
...             }
...          }
...       } 
...    },
...    {
...       "$project": {
...          "_id": 0,
...          "Name": "$_id",
...          "distinctV": 1
...       }
...    }
... ];
> db.demo586.aggregate(q);

各ステージの役割

  • $unwind:details配列を要素ごとに分解し、個々のドキュメントとして扱えるようにします。
  • $group(1回目):名前と点数の組み合わせごとにグループ化し、$sum: 1で出現回数をカウントします。
  • $group(2回目):名前ごとに再度グループ化し、$addToSetによって重複のない点数と回数のセットを生成します。
  • $project:出力から不要な_idを除外し、「Name」と「distinctV」だけを整形して表示します。

このクエリを実行すると、次のような結果が出力されます。

{ "distinctV" : [ { "value" : 61, "numberOfValues" : 1 } ], "Name" : "Carol" }
{ "distinctV" : [ { "value" : 71, "numberOfValues" : 2 }, { "value" : 61, "numberOfValues" : 1 } ], "Name" : "Chris" }
{ "distinctV" : [ { "value" : 81, "numberOfValues" : 2 } ], "Name" : "David" }

この結果から分かるように、例えば「Chris」は点数71が2回、61が1回出現していることが一目で把握できます。このように$unwind$groupを組み合わせることで、ネストされた配列データでも柔軟にdistinct選択と集計が可能になります。

  1. MySQLで一意な値を取得してカウントする方法|GROUP BY句の使い方を解説

    MySQLで一意な値を取得してカウントする方法MySQLでテーブル内の一意な(重複を除いた)値を取得し、それぞれの出現回数をカウントしたい場合は、GROUP BY句を使用します。GROUP BY句は、指定したカラムの値が同じ行を1つのグループにまとめるため、COUNT(*)関数と組み合わせることで、値ごとの件数を簡単に集計できます。基本構文構文は以下のとおりです。select yourColumnName, count(*) as anyAliasName from yourTableName group by yourColumnName;サンプルテーブルの作成実際に動作を確認するため、まず

  2. MySQLでID順に重複を除いたデータを取得するクエリ方法

    はじめにMySQLでIDに基づいて重複を除いた(distinctな)データを特定の順序で取得したい場合、GROUP BYとORDER BY MAX()を組み合わせることで実現できます。この記事では、テーブルの作成からクエリの実行まで、具体例を交えながら手順を解説します。テーブルの作成まず、サンプル用のテーブルを作成しましょう。mysql> create table DemoTable    -> (    -> Id int,    -> Name v