$lookup
MongoDB サーバー $lookupは、シャーディングされていないコレクションの左外部結合を同じデータベース内のシャーディングされていないコレクションに実行します。 ルックアップを使用すると、"join" コレクションのドキュメントをフィルタリングして処理することができるため便利です。
フェデレーティッドデータベースインスタンスでは、$lookup
を使用して、 Atlas 、 Amazon Web Services S3 、 HTTPまたはHTTPSデータストア の同じデータベースまたは異なるデータベースからのシャーディングされたコレクションとシャーディングされていないコレクションを結合できます。
注意
シャーディングされたコレクションの場合、 $lookup
は MongoDB 5.1以降を実行している Atlas クラスターでのみ使用できます。
構文
$lookup
構文については、MongoDB サーバー マニュアルを参照してください。
Data Federation では、from
の$lookup
フィールドは次の代替構文をとります。これにより、任意のデータベース名と必須のコレクション名を含むオブジェクトを指定できます。
{ $lookup: { localField: "<fieldName>", from: <collection-to-join>|{db: <db>, coll: <collection-to-join>}, foreignField: "<fieldName>", as: "<output-array-field>", } }
{ $lookup: { from: <collection to join>|{db: <db>, coll: <collection-to-join>}, let: { <var_1>: <expression>, …, <var_n>: <expression> }, pipeline: [ <pipeline to execute on the collection to join> ], as: <output array field> } }
from
フィールド オブジェクト
フィールド | タイプ | 説明 | 必要性 |
---|---|---|---|
| string | 条件付き | |
| string | コレクション名。 | 必須 |
例
たとえば、 sourceDB1
、 sourceDB2
、 sourceDB3
という名前の 3 つのデータベースがあり、次のコレクションが含まれているとします。
db.orders.insertMany([ { "_id" : 1, "item" : "almonds", "price" : 12, "quantity" : 2 }, { "_id" : 2, "item" : "pecans", "price" : 20, "quantity" : 1 }, { "_id" : 3 } ])
db.catalog.insertMany([ { "_id" : 1, "sku" : "almonds", "description": "product 1" }, { "_id" : 2, "sku" : "bread", "description": "product 2" }, { "_id" : 3, "sku" : "cashews", "description": "product 3" }, { "_id" : 4, "sku" : "pecans", "description": "product 4" }, { "_id" : 5, "sku": null, "description": "Incomplete" }, { "_id" : 6 } ])
db.warehouses.insertMany([ { "_id" : 1, "stock_item" : "almonds", "warehouse": "A", "instock" : 120 }, { "_id" : 2, "stock_item" : "pecans", "warehouse": "A", "instock" : 70 }, { "_id" : 3, "stock_item" : "cashews", "warehouse": "B", "instock" : 60 }, { "_id" : 4, "stock_item" : "bread", "warehouse": "B", "instock" : 80 }, { "_id" : 5, "stock_item" : "cookies", "warehouse": "A", "instock" : 80 } ])
次の例では、 $lookup集計ステージを使用して、1 つのコレクションのドキュメントを他のデータベース内のコレクションのドキュメントと結合します。
基本的な例
sourceDB1.orders
コレクションに対する次の集計操作は、 orders
コレクションのitem
フィールドとcatalog
のsku
フィールドを使用して、 orders
コレクションのドキュメントとsourceDB2.catalog
コレクションのドキュメントを結合します。 コレクション:
db.getSiblingDb("sourceDB1").orders.aggregate( { $lookup: { from: { db: "sourceDB2", coll: "catalog" }, localField: "item", foreignField: "sku", as: "inventory_docs" } } )
ネストされた例
sourceDB1.orders
コレクションに対する次の集計操作は、orders
sourceDB2.catalog
sourceDB3.warehouses
コレクションのitem
orders
フィールドを使用して、 コレクションのドキュメントとsku
catalog
コレクションのドキュメント、および コレクションのドキュメントを結合します。 コレクションの フィールドと、 コレクションの フィールドと フィールドstock_item
instock
warehouses
db.getSiblingDb("sourceDB1").orders.aggregate( [ { $lookup: { from: db: "sourceDB2", coll: "catalog", let: { "order_sku": "$item" }, pipeline: [ { $match: { $expr: { $eq: ["$sku", "$$order_sku"] } } }, { $lookup: { from: db: "sourceDB3", coll: "warehouses", pipeline: [ { $match: { $expr:{ $eq : ["$stock_item", "$$order_sku"] } } }, { $project : { "instock": 1, "_id": 0} } ], as: "wh" } }, { "$unwind": "$wh" }, { $project : { "description": 1, "instock": "$wh.instock", "_id": 0} } ], as: "inventory" }, }, ] )