MongoDB のルックアップオペレーターでパイプラインを使用する
このチュートリアルでは、MongoDB の lookup
演算子でパイプラインを使用する方法を説明します。先に進む前に、MongoDB の使用中に lookup
演算子でパイプラインを使用する方法を理解するために、集約パイプラインと $lookup
演算子について十分な知識を持っている必要があります。
これらの概念をすでに知っている場合は、このチュートリアルの最後の 2つのコード例にすばやく移動できます。
アグリゲーションパイプラインとは
これは、データを収集し、計算結果を返す手順です。このプロセスは、さまざまなドキュメントからデータを収集し、指定された条件に従ってそれらをグループ化し、グループ化されたデータに対してさまざまな種類の操作を実行します。
たとえば、平均、合計、最大、最小。これは、SQL 集計関数と同じです。
MongoDB では、次の 3つの方法で集計を使用できます。
-
集約パイプライン-提供されたドキュメントを変換するためのさまざまな段階が含まれています。すべてのステージがドキュメントのセットを受け入れ、結果のドキュメントの別のセットを生成して、さらに次のステージに渡します。このプロセスは、最終ステージまで続きます。
-
Map-reduce 関数-この関数を使用して、結果を大規模に集約します。
map
とreduce
の 2つの機能があります。map
メソッドはすべてのドキュメントをグループ化し、reduce
メソッドはグループ化されたデータに対して操作を実行します。 -
単一目的の集約-集約タスクを実行するために使用される最も単純な形式の集約ですが、集約パイプライン方式と比較していくつかの機能がありません。このタイプの集計を使用して、特定のドキュメント内のタスクを実行します。たとえば、特定のドキュメント内の個別の値をカウントします。
集計パイプラインをより深く知るために、こちらも参照してください。
MongoDB の $lookup
演算子とは何ですか
この演算子は、同じデータベース内のあるドキュメントから別のドキュメントにデータをマージするために左外部結合を実行するために使用されます。結合されたコレクションからドキュメントをフィルタリングして、さらに処理します。
この演算子を使用して、既存のドキュメントにフィールドを追加することもできます。
$lookup
演算子は、値(要素)が結合されたコレクションのドキュメントと一致する新しい配列属性(フィールド)を追加します。次に、これらの変換されたドキュメントは次のステージに渡されます。
$lookup
演算子には、プロジェクトの要件を考慮して使用できる 3つの異なる構文があります。このチュートリアルでは、結合されたコレクションの結合条件とサブクエリ
に $lookup
構文を使用します。
サンプルコードで練習するために、データを使用してサンプルコレクションを準備しましょう。
サンプルコード:
db.createCollection('collection1');
db.createCollection('collection2');
db.collection1.insertMany([
{"shopId": "001", "shopPosId": "001", "description": "description for 001"},
{"shopId": "002", "description": "description for 002"},
{"shopId": "003", "shopPosId": "003", "description": "description for 003"},
{"shopId": "004", "description": "description for 004"}
]);
db.collection2.insertMany([
{"shopId": "001", "shopPosId": "0078", "clientUid": "474192"},
{"shopId": "002", "shopPosId": "0012", "clientUid": "474193"},
{"shopId": "003", "shopPosId": "0034", "clientUid": "474194"},
{"shopId": "004", "shopPosId": "0056", "clientUid": "474195"}
]);
これで、次のコマンドを実行して、各コレクションに挿入されたドキュメントを確認できます。
db.collection1.find();
db.collection2.find();
$lookup
演算子でパイプラインを使用して MongoDB の条件に参加する
$lookup
演算子でパイプラインを使用する方法を学ぶために、collection1.shopId
が collection2.shopId
と等しく、collection1
に shopPosId
フィールドが含まれていない 2つのコレクションのドキュメントを結合してみましょう。。
両方の条件を満たすドキュメントのみが両方のコレクションから結合されます。以下のサンプルコードを参照してください。
サンプルコード:
db.collection2.aggregate([
{
"$lookup": {
"from": "collection1",
"let": { "shopId": "$shopId" },
"pipeline": [{
"$match": {
"$and": [
{"$expr": {"$eq": ['$shopId', '$$shopId'] }},
{ "shopPosId": { "$exists": false } }
]
}
}],
"as": "shopDescription"
}
}
]).pretty();
出力:
上記の出力を注意深く観察しましたか?パイプラインの両方の条件を満たす両方のコレクションからこれらのドキュメントのみが結合されます(collection1.shopId
は collection2.shopId
と等しく、collection1
には shopPosId
フィールドが含まれていません)。
さらに、これらの条件に一致しないドキュメントには、shopDescription
という名前の空の配列があります(上記の結果の赤いボックスを参照してください)。空でない shopDescription
配列を含む結果のドキュメントのみを表示できます(次のクエリを参照)。
サンプルコード:
db.collection2.aggregate([
{
"$lookup": {
"from": "collection1",
"let": { "shopId": "$shopId" },
"pipeline": [{
"$match": {
"$and": [
{"$expr": {"$eq": ['$shopId', '$$shopId'] }},
{ "shopPosId": { "$exists": false } }
]
}
}],
"as": "shopDescription"
}
},
{
"$match":{
"shopDescription": { $exists: true, $not: {$size: 0} }
}
}
]).pretty();
出力: