複数フィールド結合
項目一覧
はじめに
このチュートリアルでは、PyMongo を使用して集計パイプラインを構築し、コレクションに対して集計を実行し、サンプル アプリを完了して実行して結果を出力する方法を学習できます。
この集計は複数フィールド結合を実行します。 複数結合フィールドは、ドキュメントを一致させるために使用する 2 つのコレクションのドキュメントに対応するフィールドが複数ある場合に発生します。 集計は フィールド値においてこれらのドキュメントを照合し、両方の情報を 1 つのドキュメントに結合します。
Tip
1 対多の結合
1 対多結合は、複数フィールド結合の種類です。 1 対多の結合を実行すると、結合の反対側にある複数のドキュメントのフィールド値と一致するドキュメントから 1 つのフィールドが選択されます。 これらのデータ関係の詳細については、Wikipedia で 1 対多(データモデル) と多対多(データモデルモデル )に関するエントリを参照してください。
集計タスクの概要
このチュートリアルでは、製品情報を記述するコレクションのデータと、カスタマーの注文を記述する別のコレクションのデータを組み合わせる方法を説明します。 結果には、2020 年に注文された製品のリストが表示され、各注文に関する詳細も含まれています。
この例では、2 つのコレクションを使用します。
products
は、店舗が販売する商品を説明するドキュメントを含みます。orders
は、店舗内の製品の個々の注文を説明するドキュメントを含みます
注文には1つの製品しか含めることができないため、集計では複数フィールド結合を使用して製品ドキュメントと、その製品の注文を表すドキュメントを照合します。 コレクションは、name
variation
products
コレクション内のドキュメントの フィールドとproduct_name
product_variation
フィールドに対応する、orders
コレクション内のドキュメントの フィールドと フィールドによって結合されます。
始める前に
このチュートリアルを開始する前に、 集計テンプレートアプリの手順を完了して、動作する Python アプリケーションを設定してください。
products
orders
アプリを設定したら、次のコードをアプリケーションに追加して、 コレクションと コレクションにアクセスします。
products_coll = agg_db["products"] orders_coll = agg_db["orders"]
次のコードに示すように、既存の データを削除し、サンプル データをproducts
コレクションに挿入します。
products_coll.delete_many({}) products_data = [ { "name": "Asus Laptop", "variation": "Ultra HD", "category": "ELECTRONICS", "description": "Great for watching movies" }, { "name": "Asus Laptop", "variation": "Standard Display", "category": "ELECTRONICS", "description": "Good value laptop for students" }, { "name": "The Day Of The Triffids", "variation": "1st Edition", "category": "BOOKS", "description": "Classic post-apocalyptic novel" }, { "name": "The Day Of The Triffids", "variation": "2nd Edition", "category": "BOOKS", "description": "Classic post-apocalyptic novel" }, { "name": "Morphy Richards Food Mixer", "variation": "Deluxe", "category": "KITCHENWARE", "description": "Luxury mixer turning good cakes into great" } ] products_coll.insert_many(products_data)
次のコードに示すように、既存の データを削除し、サンプル データをorders
コレクションに挿入します。
orders_coll.delete_many({}) order_data = [ { "customer_id": "elise_smith@myemail.com", "orderdate": datetime(2020, 5, 30, 8, 35, 52), "product_name": "Asus Laptop", "product_variation": "Standard Display", "value": 431.43 }, { "customer_id": "tj@wheresmyemail.com", "orderdate": datetime(2019, 5, 28, 19, 13, 32), "product_name": "The Day Of The Triffids", "product_variation": "2nd Edition", "value": 5.01 }, { "customer_id": "oranieri@warmmail.com", "orderdate": datetime(2020, 1, 1, 8, 25, 37), "product_name": "Morphy Richards Food Mixer", "product_variation": "Deluxe", "value": 63.13 }, { "customer_id": "jjones@tepidmail.com", "orderdate": datetime(2020, 12, 26, 8, 55, 46), "product_name": "Asus Laptop", "product_variation": "Standard Display", "value": 429.65 } ] orders_coll.insert_many(order_data)
Tutorial
コレクションをリンクしてフィールドをインポートするためのルックアップ ステージを追加します
パイプラインの最初のステージは$lookupステージで、各コレクション内の 2 つのフィールドでorders
コレクションとproducts
コレクションに結合されます。 ルックアップステージには、結合を構成するための埋め込みパイプラインが含まれています。
埋め込みパイプライン内に、結合の両方にある 2 つのフィールドの値を一致させるために$matchステージを追加します。 次のコードでは、 ステージの作成時に設定されたname
variation
フィールドと$lookup
フィールドのエイリアスを使用していることに注意してください。
embedded_pl = [ { "$match": { "$expr": { "$and": [ {"$eq": ["$product_name", "$$prdname"]}, {"$eq": ["$product_variation", "$$prdvartn"]} ] } } } ]
埋め込みパイプライン内に、 2020での注文と一致するように別の$matchステージを追加します。
embedded_pl.append({ "$match": { "orderdate": { "$gte": datetime(2020, 1, 1, 0, 0, 0), "$lt": datetime(2021, 1, 1, 0, 0, 0) } } })
埋め込みパイプライン内に、結合のorders
コレクション側から不要なフィールドを削除する$unsetステージを追加します。
embedded_pl.append({ "$unset": ["_id", "product_name", "product_variation"] })
埋め込みパイプラインが完了したら、メインの集計パイプラインに$lookup
ステージを追加します。 このステージを構成して、処理されたルックアップ フィールドをorders
という配列フィールドに保存します。
pipeline.append({ "$lookup": { "from": "orders", "let": { "prdname": "$name", "prdvartn": "$variation" }, "pipeline": embedded_pl, "as": "orders" } })
2020 年注文製品の一致ステージを追加
次に、前のステップで計算されたorders
配列に基づいて、 2020に少なくとも 1 回の注文がある製品のみを表示する$matchステージを追加します。
pipeline.append({ "$match": { "orders": {"$ne": []} } })
不要なフィールドを削除するために設定されていない ステージを追加します
最後に、 $unsetステージを追加します。 $unset
ステージでは、結果ドキュメントから フィールドと フィールドが削除されます。_id
description
pipeline.append({ "$unset": ["_id", "description"] })
結果の解釈
集計された結果には 2 つのドキュメントが含まれています。 ドキュメントは、2020 年に注文が行われた製品を表しています。 各ドキュメントには、その製品の各注文に関する詳細を一覧表示するorders
配列フィールドが含まれています。
{ 'name': 'Asus Laptop', 'variation': 'Standard Display', 'category': 'ELECTRONICS', 'orders': [ { 'customer_id': 'elise_smith@myemail.com', 'orderdate': datetime.datetime(2020, 5, 30, 8, 35, 52), 'value': 431.43 }, { 'customer_id': 'jjones@tepidmail.com', 'orderdate': datetime.datetime(2020, 12, 26, 8, 55, 46), 'value': 429.65 } ] } { 'name': 'Morphy Richards Food Mixer', 'variation': 'Deluxe', 'category': 'KITCHENWARE', 'orders': [ { 'customer_id': 'oranieri@warmmail.com', 'orderdate': datetime.datetime(2020, 1, 1, 8, 25, 37), 'value': 63.13 } ] }
結果ドキュメントには、 orders
コレクションとproducts
コレクション内のドキュメントの詳細が、製品名とバリエーションで結合されたものが含まれます。
このチュートリアルの完全なコードを表示するには、「 完了した マルチフィールド結合アプリ Github」を参照してください。 .