Docs Menu

Docs Homeアプリケーションの開発Python ドライバーPyMongo

複数フィールド結合

項目一覧

  • はじめに
  • 集計タスクの概要
  • 始める前に
  • Tutorial
  • コレクションをリンクしてフィールドをインポートするためのルックアップ ステージを追加します
  • 2020 年注文製品の一致ステージを追加
  • 不要なフィールドを削除するために設定されていない ステージを追加します
  • 集計パイプラインの実行
  • 結果の解釈

このチュートリアルでは、PyMongo を使用して集計パイプラインを構築し、コレクションに対して集計を実行し、サンプル アプリを完了して実行して結果を出力する方法を学習できます。

この集計は複数フィールド結合を実行します。 複数結合フィールドは、ドキュメントを一致させるために使用する 2 つのコレクションのドキュメントに対応するフィールドが複数ある場合に発生します。 集計は フィールド値においてこれらのドキュメントを照合し、両方の情報を 1 つのドキュメントに結合します。

Tip

1 対多の結合

1 対多結合は、複数フィールド結合の種類です。 1 対多の結合を実行すると、結合の反対側にある複数のドキュメントのフィールド値と一致するドキュメントから 1 つのフィールドが選択されます。 これらのデータ関係の詳細については、Wikipedia で 1 対多(データモデル) に関するエントリを参照してください。 および 多対多 (データモデル)

このチュートリアルでは、製品情報を記述するコレクションのデータと、カスタマーの注文を記述する別のコレクションのデータを組み合わせる方法を説明します。 結果には、2020 年に注文された製品のリストが表示され、各注文に関する詳細も含まれています。

この例では、2 つのコレクションを使用します。

  • productsは、店舗が販売する商品を説明するドキュメントを含みます。

  • ordersは、店舗内の製品の個々の注文を説明するドキュメントを含みます

注文には1つの製品しか含めることができないため、集計では複数フィールド結合を使用して製品ドキュメントと、その製品の注文を表すドキュメントを照合します。 コレクションは、name variationproductsコレクション内のドキュメントの フィールドとproduct_name product_variationフィールドに対応する、orders コレクション内のドキュメントの フィールドと フィールドによって結合されます。

このチュートリアルを開始する前に、集計テンプレートアプリの手順を完了して、動作する Python アプリケーションを設定してください。

productsordersアプリを設定したら、次のコードをアプリケーションに追加して、 コレクションと コレクションにアクセスします。

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)
1

パイプラインの最初のステージは$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"
}
})
2

次に、前のステップで計算されたorders配列に基づいて、 2020に少なくとも 1 回の注文がある製品のみを表示する$matchステージを追加します。

pipeline.append({
"$match": {
"orders": {"$ne": []}
}
})
3

最後に、 $unsetステージを追加します。 $unsetステージでは、結果ドキュメントから フィールドと フィールドが削除されます。_iddescription

pipeline.append({
"$unset": ["_id", "description"]
})
4

次のコードをアプリケーションの末尾に追加して、 productsコレクションで集計を実行します。

aggregation_result = products_coll.aggregate(pipeline)

最後に、shell で次のコマンドを実行してアプリケーションを起動します。

python3 agg_tutorial.py
5

集計された結果には 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」を参照してください。 .

← 1 対 1 の結合