MongoDB 聚合クエリの概要#
MongoDB は効率的なドキュメントデータベースであり、次のようなデータの保存に使用できます。
データを検索する際に、フィルタ条件を結合して条件に合致するデータを返すことができますが、通常、これらのデータは直接使用や転送はできません。
バックエンドで再加工してフロントエンドアプリケーションに返す必要があります。たとえば、特定のユーザーのすべての投稿を検索する場合は、同様の操作です。通常、個人情報と投稿情報は別々のテーブルに保存されます。指定したユーザーの投稿を知りたい場合は、テーブルの関連付けされたクエリを実行する必要があります。リレーショナルデータベースに詳しい場合、このような操作をより理解しやすいでしょう。なぜなら、このようなテーブルの関連付けクエリは日常の開発で非常に一般的だからです〜
Mongo では、Aggregate コマンドは集計クエリに使用されるメソッドであり、パラメータを追加しない場合は find メソッドと同等です。その形式は次のようになります。
collection.aggregate([ステージ1,ステージ2,……,ステージN])
ステージ指令には、データのフィルタリングに使用される $match、フィールドに関連する操作に使用される $project、グループ化に使用される $group、データの展開に使用される $unwind、テーブルの関連付けに使用される $lookup などがあります。
データのフィルタリング#
db.getCollection('example_user').aggregate([
{"$match":{
"name":"姜大牛",
"id":{"$lt":2}
}}
])
$match のパラメータは find の最初のパラメータと同じです。フィールドの一致や範囲の一致を使用することができます。
フィールドの調整#
db.getCollection('example_user').aggregate([
{"$project":{
"_id":0, //_idを非表示にする
"id":"$id", //カスタムidを参照する
"名前":"$address", //フィールド名を変更する
"work":"作家", //フィールドを追加する
"isLogin":{"$literal":1}, //デフォルト値は1または0
"hello":{"$literal":"$美元"} //デフォルト値には$が含まれる
}}
])
$project のパラメータは find の 2 番目のパラメータと似ていますが、より多くの操作オプションがあります。既存のフィールドを追加または変更することができますし、サブドキュメントのフィールドを追加することもできます。結果で「$」や 1、0 をデフォルト値として使用する必要がある場合は、$literal を使用して Mongo の構文との衝突を防ぐことができます。
データのグループ化#
グループ化関数
db.getCollection('example_data').aggregate([
{"$group":{
"_id":"$name"
}}
])
重複のない関数
db.getCollection('example_data').distinct("name")
まず、重複のない関数とグループ化関数を比較すると、明らかな違いがあることがわかります。グループ化されたデータは 1 行ごとに返されますが、重複のないデータは配列内に返されます。スコア情報、平均値などのより多くのフィールドを返す必要がある場合は、グループ化情報を使用する方が適しています。グループ化情報をさらに充実させてみましょう。
db.getCollection('example_data').aggregate([{
"$group":{
"_id":"$name",
"max_score":{"$max":"$score"}, //最大値を取得する
"min_score":{"$min":"$score"}, //最小値を取得する
"avg_score":{"$avg":"$score"}, //平均値を取得する
"sum_score":{"$sum":"$score"}, //合計を取得する
"first_score":{"$first":"$score"}, //最初の値を取得する
"last_score":{"$last":"$score"}, //最後の値を取得する
}
}])
データの展開#
データに配列が含まれている場合、データを展開して処理する必要があります。
db.getCollection('example_tshirt').aggregate([
{"$unwind":"$size"}
])
複数のフィールドを展開することもできます。
db.getCollection('example_tshirt').aggregate([
{"$unwind":"$size"},
{"$unwind":"$color"}
])
コレクションの結合クエリ#
結合クエリは SQL の JOIN クエリに相当し、複数のコレクションのデータを統合して必要なデータを取得することができます。形式は次のようになります。
メインコレクション.aggregate([
{"$lookup":{
"from":"関連コレクション",
"localField":"メインコレクションのフィールド",
"foreignField":"関連コレクションのフィールド",
"as":"関連コレクションのエイリアス"
}}
])
たとえば、ユーザーがどの投稿を書いたかをクエリしたい場合は、次の形式で書くことができます。
もちろん、このデータ形式は私たちにとって十分ではありません。データを最適化することができます。
その他#
Mongo を使い終わったら、使いたくなるはずです。Python では pymongo というライブラリがあり、ほぼ Mongo のコマンドをそのまま使うことができます。これにより、学習コストが削減され、非常に便利です。
詳細はこちらをご覧ください。