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

MongoDBで複数のキーを使ったdistinct(重複排除)を効率的に実行する方法

MongoDBで複数のキーを使ったdistinct(重複排除)を効率的に実行する方法

MongoDBでは、アグリゲーションフレームワーク(集計フレームワーク)を活用することで、複数のキーを組み合わせたdistinct処理を効率的に実行できます。標準のdistinctコマンドは基本的に単一フィールドしか指定できませんが、$groupステージを使えば、複数フィールドの組み合わせで重複を排除できます。

ここでは、実際にコレクションを作成しながら、具体的な手順を詳しく見ていきましょう。

ステップ1:サンプルコレクションの作成

まず、動作を理解するためにドキュメントを格納するコレクションを作成します。以下のクエリを実行して、ドキュメントを挿入してください。

> db.distinctWithMultipleKeysDemo.insertOne({"StudentName":"Mike","StudentAge":22,"StudentMathMarks":56});
{
    "acknowledged" : true,
    "insertedId" : ObjectId("5c7f74488d10a061296a3c53")
}
> db.distinctWithMultipleKeysDemo.insertOne({"StudentName":"Mike","StudentAge":22,"StudentMathMarks":56});
{
    "acknowledged" : true,
    "insertedId" : ObjectId("5c7f744b8d10a061296a3c54")
}
> db.distinctWithMultipleKeysDemo.insertOne({"StudentName":"Bob","StudentAge":23,"StudentMathMarks":45});
{
    "acknowledged" : true,
    "insertedId" : ObjectId("5c7f74598d10a061296a3c55")
}
> db.distinctWithMultipleKeysDemo.insertOne({"StudentName":"Bob","StudentAge":23,"StudentMathMarks":45});
{
    "acknowledged" : true,
    "insertedId" : ObjectId("5c7f745e8d10a061296a3c56")
}
> db.distinctWithMultipleKeysDemo.insertOne({"StudentName":"Carol","StudentAge":27,"StudentMathMarks":54});
{
    "acknowledged" : true,
    "insertedId" : ObjectId("5c7f74688d10a061296a3c57")
}

ステップ2:登録データの確認

find()メソッドを使って、コレクション内のすべてのドキュメントを表示してみましょう。

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

実行すると、以下のように5件のドキュメントが表示されます。このうち「Mike」と「Bob」のデータは、それぞれ2件ずつ重複して登録されている点に注目してください。

{
    "_id" : ObjectId("5c7f74488d10a061296a3c53"),
    "StudentName" : "Mike",
    "StudentAge" : 22,
    "StudentMathMarks" : 56
}
{
    "_id" : ObjectId("5c7f744b8d10a061296a3c54"),
    "StudentName" : "Mike",
    "StudentAge" : 22,
    "StudentMathMarks" : 56
}
{
    "_id" : ObjectId("5c7f74598d10a061296a3c55"),
    "StudentName" : "Bob",
    "StudentAge" : 23,
    "StudentMathMarks" : 45
}
{
    "_id" : ObjectId("5c7f745e8d10a061296a3c56"),
    "StudentName" : "Bob",
    "StudentAge" : 23,
    "StudentMathMarks" : 45
}
{
    "_id" : ObjectId("5c7f74688d10a061296a3c57"),
    "StudentName" : "Carol",
    "StudentAge" : 27,
    "StudentMathMarks" : 54
}

ステップ3:$groupを使った複数キーのdistinct

いよいよ本題です。アグリゲーションパイプラインの$groupステージで_idに複数のフィールドを指定することで、複数キーによる重複排除が実現できます。

> c = db.distinctWithMultipleKeysDemo;
test.distinctWithMultipleKeysDemo
> myResult = c.aggregate( [ {"$group": { "_id": { StudentName:"$StudentName", StudentAge: "$StudentAge" } } } ] );

実行結果は以下のとおりです。

{ "_id" : { "StudentName" : "Carol", "StudentAge" : 27 } }
{ "_id" : { "StudentName" : "Bob", "StudentAge" : 23 } }
{ "_id" : { "StudentName" : "Mike", "StudentAge" : 22 } }

StudentNameStudentAgeの組み合わせが一意になるようグループ化され、重複していた2組のデータがそれぞれ1件にまとめられました。その結果、3件のユニークな組み合わせだけを取得できています。

応用:結果を見やすく整形する

さらに$project$sortを組み合わせると、_idの中身を展開したフラットな形式で出力したり、任意の順序で並べ替えたりすることも可能です。

> db.distinctWithMultipleKeysDemo.aggregate([
...   { "$group": { "_id": { StudentName: "$StudentName", StudentAge: "$StudentAge" } } },
...   { "$project": { "_id": 0, "StudentName": "$_id.StudentName", "StudentAge": "$_id.StudentAge" } },
...   { "$sort": { "StudentName": 1 } }
... ]);

このクエリを実行すると、名前の昇順にソートされた、読みやすい形式の結果が得られます。

まとめ

MongoDBで複数キーのdistinctを実現したい場合は、アグリゲーションフレームワークの$groupステージを使うのが定番のアプローチです。単一フィールドのdistinctコマンドでは対応できないケースでも、柔軟かつ効率的に重複排除を行えます。なお、大量のドキュメントを扱う場合は、_idに指定するフィールドにインデックスを作成しておくと、集計処理のパフォーマンス向上が期待できます。

  1. MongoDBのaggregate()を使って複数のドキュメントをマージ(統合)する方法

    MongoDBで複数のドキュメントをマージするには? MongoDBで複数のドキュメントを1つにマージ(統合)したい場合は、aggregate()メソッドを使用します。集計パイプラインの各ステージ($sort、$unwind、$group、$addFields、$projectなど)を組み合わせることで、特定のフィールドをキーにしてドキュメントをグループ化し、配列や数値をまとめることができます。 ここでは、実際にサンプルコレクションを作成しながら、具体的な手順を解説します。 1. コレクションの作成とドキュメントの挿入 まず、insertOne()メソッドを使ってサンプルコレクション「dem

  2. MongoDBで配列内の要素数をカウントする方法

    MongoDBで配列内の要素数をカウントする基本MongoDBで配列(Array)内のアイテム数をカウントするには、lengthプロパティを使用します。この記事では、実際にコレクションを作成し、配列の要素数を取得するまでの手順を実行例付きで解説します。1. コレクションにドキュメントを挿入するまず、insertOne()メソッドを使って、配列フィールドを持つドキュメントを含むコレクションを作成しましょう。> db.demo440.insertOne( ...    { ...       "Name":"Ch