Docs Menu
Docs Home
/ / /
Node.js
/

複数フィールド結合

項目一覧

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

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

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

Tip

1 対多の結合

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

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

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

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

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

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

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

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

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

パイプラインの最初のステージは$lookupステージで、各コレクション内の 2 つのフィールドでordersコレクションとproductsコレクションに結合されます。 ルックアップステージには、結合を構成するための埋め込みパイプラインが含まれています。

埋め込みパイプライン内に、結合の両方にある 2 つのフィールドの値を一致させるために$matchステージを追加します。 次のコードでは 、$lookup ステージの作成 時に設定された フィールドと フィールドのエイリアスを使用していることに注意してください。namevariation

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",
},
});
2

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

pipeline.push({
$match: {
orders: { $ne: [] },
},
});
3

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

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

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

const aggregationResult = await productsColl.aggregate(pipeline);

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

node agg_tutorial.js
5

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

戻る

1 対 1 の結合