1 対 1 の結合
項目一覧
はじめに
このチュートリアルでは、PyMongo を使用して集計パイプラインを構築し、コレクションに対して集計を実行し、サンプル アプリを完了して実行して結果を出力する方法を学習できます。
この集計では 1 対 1 の結合が実行されます。 1 対 1 の結合は、1 つのコレクション内のドキュメントの フィールド値が、同じフィールド値を持つ別のコレクション内の単一のドキュメントと一致する場合に行われます。 集計は フィールド値でこれらのドキュメントを照合し、両方のソースからの情報を 1 つの結果に結合します。
Tip
1 対 1 の結合では、ドキュメントに 1 対 1 の関係必要はありません。 この データ関係の詳細については、 Wikipedia の 1 対 1(データモデル)に関するエントリを参照してください。
集計タスクの概要
このチュートリアルでは、製品情報を記述するコレクションのデータと、カスタマーの注文を記述する別のコレクションのデータを組み合わせる方法を説明します。 結果には、2020 年に行われたすべての注文のリストが表示され、各注文に関連付けられた製品の詳細が含まれます。
この例では、2 つのコレクションを使用します。
orders
: 店舗内の製品の個々の注文を説明するドキュメントが含まれていますproducts
: 店舗が販売する商品を説明するドキュメントが含まれています
注文には1つの製品しか含めることができないため、集計では 1 対 1 の結合を使用して注文ドキュメントと製品のドキュメントを照合します。 コレクションは、両方のコレクションのドキュメントに存在するproduct_id
というフィールドによって結合されます。
始める前に
このチュートリアルを開始する前に、 集計テンプレートアプリの手順を完了して、動作する Python アプリケーションを設定してください。
orders
products
アプリを設定したら、次のコードをアプリケーションに追加して、 コレクションと コレクションにアクセスします。
orders_coll = agg_db["orders"] products_coll = agg_db["products"]
次のコードに示すように、既存の データを削除し、サンプル データをorders
コレクションに挿入します。
orders_coll.delete_many({}) order_data = [ { "customer_id": "elise_smith@myemail.com", "orderdate": datetime(2020, 5, 30, 8, 35, 52), "product_id": "a1b2c3d4", "value": 431.43 }, { "customer_id": "tj@wheresmyemail.com", "orderdate": datetime(2019, 5, 28, 19, 13, 32), "product_id": "z9y8x7w6", "value": 5.01 }, { "customer_id": "oranieri@warmmail.com", "orderdate": datetime(2020, 1, 1, 8, 25, 37), "product_id": "ff11gg22hh33", "value": 63.13 }, { "customer_id": "jjones@tepidmail.com", "orderdate": datetime(2020, 12, 26, 8, 55, 46), "product_id": "a1b2c3d4", "value": 429.65 } ] orders_coll.insert_many(order_data)
次のコードに示すように、既存の データを削除し、サンプル データをproducts
コレクションに挿入します。
products_coll.delete_many({}) product_data = [ { "id": "a1b2c3d4", "name": "Asus Laptop", "category": "ELECTRONICS", "description": "Good value laptop for students" }, { "id": "z9y8x7w6", "name": "The Day Of The Triffids", "category": "BOOKS", "description": "Classic post-apocalyptic novel" }, { "id": "ff11gg22hh33", "name": "Morphy Richardds Food Mixer", "category": "KITCHENWARE", "description": "Luxury mixer turning good cakes into great" }, { "id": "pqr678st", "name": "Karcher Hose Set", "category": "GARDEN", "description": "Hose + nosels + winder for tidy storage" } ] products_coll.insert_many(product_data)
Tutorial
2020 年注文の一致ステージを追加します
2020での注文に一致する$matchステージを追加します。
pipeline.append({ "$match": { "orderdate": { "$gte": datetime(2020, 1, 1, 0, 0, 0), "$lt": datetime(2021, 1, 1, 0, 0, 0) } } })
コレクションをリンクするためにルックアップ ステージを追加します
次に、 $lookupステージを追加します。 $lookup
ステージは、 orders
コレクションのproduct_id
フィールドをproducts
コレクションのid
フィールドに結合します。
pipeline.append({ "$lookup": { "from": "products", "localField": "product_id", "foreignField": "id", "as": "product_mapping" } })
新しいドキュメントフィールドを作成するにはセットステージを追加します
次に、パイプラインに 2 つの$setステージを追加します。
最初の$set
ステージは、 product_mapping
フィールドを、前の$lookup
ステージで作成されたproduct_mapping
オブジェクトの最初の要素に設定します。
2 つ目の$set
ステージでは、 product_mapping
オブジェクト フィールドの値から 2 つの新しいフィールド ( product_name
とproduct_category
)が作成されます。
pipeline.extend([ { "$set": { "product_mapping": {"$first": "$product_mapping"} } }, { "$set": { "product_name": "$product_mapping.name", "product_category": "$product_mapping.category" } } ])
Tip
これは 1 対 1 の結合であるため、 $lookup
ステージは入力ドキュメントに 1 つの配列要素のみを追加します。 パイプラインは$first演算子を使用して、この要素からデータを検索します。
不要なフィールドを削除するために設定されていない ステージを追加します
最後に、 $unsetステージを追加します。 $unset
ステージは、ドキュメントから不要なフィールドを削除します。
pipeline.append({"$unset": ["_id", "product_id", "product_mapping"]})
結果の解釈
集計された結果には 3 つのドキュメントが含まれます。 ドキュメントは、注文製品のproduct_name
とproduct_category
を含む、2020 年に発生したカスタマーの注文を表します。
{ 'customer_id': 'elise_smith@myemail.com', 'orderdate': datetime.datetime(2020, 5, 30, 8, 35, 52), 'value': 431.43, 'product_name': 'Asus Laptop', 'product_category': 'ELECTRONICS' } { 'customer_id': 'oranieri@warmmail.com', 'orderdate': datetime.datetime(2020, 1, 1, 8, 25, 37), 'value': 63.13, 'product_name': 'Morphy Richardds Food Mixer', 'product_category': 'KITCHENWARE' } { 'customer_id': 'jjones@tepidmail.com', 'orderdate': datetime.datetime(2020, 12, 26, 8, 55, 46), 'value': 429.65, 'product_name': 'Asus Laptop', 'product_category': 'ELECTRONICS' }
結果は、 orders
コレクションとproducts
コレクション内のドキュメントのフィールドを含むドキュメントで構成されており、各元のドキュメントに存在するproduct_id
フィールドを一致させて結合されます。
このチュートリアルの完全なコードを表示するには、「 完了した 1 対 1 の結合アプリ Github」を参照してください。 .