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