AI エージェント向け: ドキュメントインデックスは https://www.mongodb.com/ja-jp/docs/llms.txt で利用できます。すべてのページの markdown バージョンは、いずれかの URL パスに .md を追加することで利用できます。
Docs Menu

$lookup(集計ステージ)

$lookup

バージョン5.1で変更。

Performs a left outer join to a collection in the same database to filter in documents from the foreign collection for processing. The $lookup stage adds a new array field to each input document. The new array field contains the matching documents from the foreign collection. The $lookup stage passes these reshaped documents to the next stage.

Starting in MongoDB 5.1, you can use $lookup with sharded collections.

2 つの異なるコレクションの要素を結合するには、 $unionWithパイプライン ステージを使用します。

重要

$lookup performance, as with any other query performance, depends on the operation type and whether the foreign field is indexed. Unindexed or correlated-subquery $lookup operations on large collections can slow down query performance. To reduce reliance on $lookup, consider an embedded data model to store related data in a single collection.

For details on $lookup performance by operation type, see Performance Considerations.

次の環境でホストされる配置には $lookup を使用できます。

  • MongoDB Atlas はクラウドでの MongoDB 配置のための完全管理サービスです
  • MongoDB Enterprise: サブスクリプションベースの自己管理型 MongoDB バージョン

  • MongoDB Community: ソースが利用可能で、無料で使用できる自己管理型の MongoDB のバージョン

The $lookup stage syntax:

{
$lookup:
{
from: <collection to join>,
localField: <field from the input documents>,
foreignField: <field from the documents of the "from" collection>,
let: { <var_1>: <expression>, …, <var_n>: <expression> },
pipeline: [ <pipeline to run> ],
as: <output array field>
}
}

The $lookup accepts a document with these fields:

フィールド
必要性
説明

必須

ローカルコレクションに結合する同じデータベース内の外部コレクションを指定します。

場合によっては、$documents を第 1 ステージとして、frompipeline に置き換えることができます。例については、「 $lookup ステージで $documents ステージを使用する 」を参照してください。

MongoDB 5.1 以降では、 fromコレクションをシャーディングできます。

pipelineが指定されている場合は任意

Specifies the field from the documents input to the $lookup stage. $lookup performs an equality match on the localField to the foreignField from the documents of the from collection. If an input document does not contain the localField, the $lookup treats the field as having a value of null for matching purposes.

pipelineが指定されている場合は任意

外部ドキュメントの foreignField を指定して、ローカルドキュメントの localField と等価一致を実行します。

If a foreign document does not contain a foreignField value, the $lookup uses a null value for the match.

任意

Specifies variables to use in the pipeline stages. Use the variable expressions to access the fields from the local collection's documents that are input to the pipeline.

To reference variables in pipeline stages, use the "$$<variable>" syntax.

The let variables can be accessed by the stages in the pipeline, including additional $lookup stages nested in the pipeline.

  • $matchステージでは、変数にアクセスするために$expr演算子を使用する必要があります。$expr演算子を使用すると、$match構文内で集計式を使用できます。

    The $eq, $lt, $lte, $gt, and $gte comparison operators placed in an $expr operator can use an index on the from collection referenced in a $lookup stage. Limitations:

    • インデックスはフィールドと定数の比較にのみ使用できるため、let オペランドは定数に変換する必要があります。

      たとえば、$a と定数値の比較にはインデックスを使用できますが、$a$b の比較には使用できません。

    • let オペランドが空の値または欠損値に変換される場合の比較には、インデックスは使用されません。

    • マルチキー部分、またはスパースインデックスは使用されません。

  • Other (non-$match) stages in the pipeline do not require an $expr operator to access the variables.

localFieldforeignField が指定されている場合は任意です。

外部コレクションで実行するpipelineを指定します。pipelineは外部コレクションからドキュメントを返します。すべてのドキュメントを返すには、空のpipeline: []を指定します。

にはpipeline $out$mergeステージまたは ステージを含めることはできません。 v6.0 以降では、pipeline にはパイプライン内の最初のステージとして$search Atlas Search ステージを含めることができます。詳しくは、「 Atlas Search サポート 」を参照してください。

The pipeline cannot access fields from input documents. Instead, define variables for the document fields using the let option and then reference the variables in the pipeline stages.

To reference variables in pipeline stages, use the "$$<variable>" syntax.

The let variables can be accessed by the stages in the pipeline, including additional $lookup stages nested in the pipeline.

  • $matchステージでは、変数にアクセスするために$expr演算子を使用する必要があります。$expr演算子を使用すると、$match構文内で集計式を使用できます。

    The $eq, $lt, $lte, $gt, and $gte comparison operators placed in an $expr operator can use an index on the from collection referenced in a $lookup stage. Limitations:

    • インデックスはフィールドと定数の比較にのみ使用できるため、let オペランドは定数に変換する必要があります。

      たとえば、$a と定数値の比較にはインデックスを使用できますが、$a$b の比較には使用できません。

    • let オペランドが空の値または欠損値に変換される場合の比較には、インデックスは使用されません。

    • マルチキー部分、またはスパースインデックスは使用されません。

  • Other (non-$match) stages in the pipeline do not require an $expr operator to access the variables.

必須

入力ドキュメントに追加する新しい配列フィールドの名前を指定します。新しい配列フィールドには、fromコレクションと一致するドキュメントが含まれます。指定した名前がすでに入力ドキュメントに存在する場合、既存のフィールドは上書きされます。

To perform an equality match between a field from the input documents with a field from the documents of the foreign collection, the $lookup stage has this syntax:

{
$lookup:
{
from: <collection to join>,
localField: <field from the input documents>,
foreignField: <field from the documents of the "from" collection>,
pipeline: [ <pipeline to run> ],
as: <output array field>
}
}

注意

この例では 、pipeline は任意であり、ローカルと外部の等価ステージの後に実行されます。

この操作は、次の疑似 SQL ステートメントに対応します。

SELECT *, (
SELECT ARRAY_AGG(*)
FROM <collection to join>
WHERE <foreignField> = <collection.localField>
) AS <output array field>
FROM collection;

注意

このページの SQL ステートメントは、MongoDB 集計パイプライン構文の比較に含まれています。SQL ステートメントは実行できません。

MongoDB の例については、次のページを参照してください。

MongoDB は以下をサポートします。

  • 外部コレクションでパイプラインを実行する。

  • 複数の結合条件。

  • 相関サブクエリと非相関サブクエリ。

In MongoDB, an uncorrelated subquery means that every input document returns the same result. A correlated subquery is a pipeline in a $lookup stage that uses the local or input collection's fields to return results correlated to each incoming document.

注意

Starting in MongoDB 5.0, for an uncorrelated subquery in a $lookup pipeline stage containing a $sample stage, the $sampleRate operator, or the $rand operator, the subquery is always run again if repeated. Previously, depending on the subquery output size, either the subquery output was cached or the subquery was run again.

MongoDB 相関サブクエリは、内部クエリが外部クエリ値を参照する SQL 相関サブクエリに相当します。SQL 非相関サブクエリは、外部クエリ値を参照しません。

MongoDB 5.0 は簡潔な相関サブクエリもサポートしています。

To perform correlated and uncorrelated subqueries with two collections, and perform other join conditions besides a single equality match, use this $lookup syntax:

{
$lookup:
{
from: <foreign collection>,
let: { <var_1>: <expression>, …, <var_n>: <expression> },
pipeline: [ <pipeline to run on foreign collection> ],
as: <output array field>
}
}

この操作は、次の疑似 SQL ステートメントに対応します。

SELECT *, <output array field>
FROM collection
WHERE <output array field> IN (
SELECT <documents as determined from the pipeline>
FROM <collection to join>
WHERE <pipeline>
);

次の例を参照してください。

バージョン 5.0 の新機能。

MongoDB 5.0 以降、簡潔な相関サブクエリの構文を使用できるようになりました。相関サブクエリは、外部コレクションおよびaggregate()メソッドが実行された「ローカル」コレクションのドキュメントフィールドを参照します。

The following new concise syntax removes the requirement for an equality match on the foreign and local fields inside an $expr operator:

{
$lookup:
{
from: <foreign collection>,
localField: <field from local collection's documents>,
foreignField: <field from foreign collection's documents>,
let: { <var_1>: <expression>, …, <var_n>: <expression> },
pipeline: [ <pipeline to run> ],
as: <output array field>
}
}

この操作は、次の疑似 SQL ステートメントに対応します。

SELECT *, <output array field>
FROM localCollection
WHERE <output array field> IN (
SELECT <documents as determined from the pipeline>
FROM <foreignCollection>
WHERE <foreignCollection.foreignField> = <localCollection.localField>
AND <pipeline match condition>
);

以下の例を参照してください。

If performing an aggregation that involves multiple views, such as with $lookup or $graphLookup, the views must have the same collation.

You cannot include the $out or the $merge stage in the $lookup stage. That is, when specifying a pipeline for the foreign collection, you cannot include either stage in the pipeline field.

{
$lookup:
{
from: <collection to join>,
let: { <var_1>: <expression>, …, <var_n>: <expression> },
pipeline: [ <pipeline to execute on the foreign collection> ], // Cannot include $out or $merge
as: <output array field>
}
}

MongoDB6.0 以降では、 パイプラインで Atlas Search$search $searchMetaまたは$lookup ステージを指定して、Atlas クラスター上のコレクションを検索できます。$search $searchMetaまたは ステージは、$lookup パイプライン内の最初のステージである必要があります。

For example, when you Join Conditions and Subqueries on a Foreign Collection or run Correlated Subqueries Using Concise Syntax, you can specify $search or $searchMeta inside the pipeline as shown below:

[{
"$lookup": {
"from": <foreign collection>,
localField: <field from the input documents>,
foreignField: <field from the documents of the "from" collection>,
"as": <output array field>,
"pipeline": [{
"$search": {
"<operator>": {
<operator-specification>
}
},
...
}]
}
}]
[{
"$lookup": {
"from": <foreign collection>,
localField: <field from the input documents>,
foreignField: <field from the documents of the "from" collection>,
"as": <output array field>,
"pipeline": [{
"$searchMeta": {
"<collector>": {
<collector-specification>
}
},
...
}]
}
}]

To see an example of $lookup with $search, see the Atlas Search tutorial Run an Atlas Search $search Query Using $lookup.

Starting in MongoDB 5.1, you can specify sharded collections in the from parameter of $lookup stages.

シャーディングされたコレクションをターゲットにしている間は、トランザクション内で $lookup ステージを使用できません

注意

バージョン 7.0.17 以降、スロットベースのクエリ実行エンジンは、7.0 のパッチ バージョンではデフォルトで有効ではなくなりました。スロットベースのクエリ実行エンジンを使用するクエリを使用する場合は、バージョン 8.0 にアップグレードしてください。デフォルトで有効になっている 。

Starting in version 6.0, MongoDB can use the slot-based execution query engine to execute $lookup stages if all preceding stages in the pipeline can also be executed by the slot-based execution engine and none of the following conditions are true:

  • $lookup 操作は、外部コレクションに対してパイプラインを実行します。この種の操作の例については、「外部コレクションの結合条件とサブクエリ」を参照してください。

  • $lookuplocalField または foreignField は数値コンポーネントを指定します。例: { localField: "restaurant.0.review" }

  • パイプラインに含まれる任意の $lookupfrom フィールドには、ビューまたはシャーディングされたコレクションが明示されます。

詳細については、「$lookup 最適化」を参照してください。

$lookup パフォーマンスは、実行される操作の種類によって異なります。さまざまな$lookup操作のパフォーマンスに関する考慮事項については、次の表を参照してください。

$lookup 操作
パフォーマンスに関する考慮事項
  • $lookup では、外部コレクションに foreignField のインデックスが含まれている場合、単一結合で等価一致を実行する操作のパフォーマンスが向上します。

    IMPORTANT: If a supporting index on the foreignField does not exist, a $lookup operation that performs an equality match with a single join likely has poor performance.

  • $lookup では、内部パイプラインが外部コレクションのインデックスを参照できる場合、非相関サブクエリを含む操作のパフォーマンスが向上します。

  • ソース コレクションと外部コレクションの間には関係がないため、MongoDB はクエリをキャッシュする前に $lookup サブクエリを一度だけ実行する必要があります。サブクエリはソース コレクション内のどの値にも基づいていません。この動作により、 $lookup 操作の後続の実行時のパフォーマンスが向上します。

  • $lookup operations that contain correlated subqueries perform better when the foreign collection contains an index on the foreignField.

  • パイプラインが多数のドキュメントを $lookup クエリに渡す場合、次の戦略によってパフォーマンスが向上する可能性があります。

    • MongoDB が$lookupクエリに渡すドキュメントの数を減らします。たとえば、$match ステージでより厳しいフィルターを設定します。

    • データのスキーマを再検討して、ユースケースに最適であることを確認します。

一般的なパフォーマンス戦略については、「インデックス戦略」と「クエリの最適化」を参照してください。

このページの例では、sample_mflixサンプルデータセットのデータを使用します。このデータセットを自己管理型MongoDB配置にロードする方法の詳細については、サンプルデータセットをロードする を参照してください。サンプルデータベースに変更を加えた場合、このページの例を実行するには、データベースを削除して再作成する必要がある場合があります。

次の集計操作では、まず moviesコレクションをruntime1000 より大きい映画をフィルタリングし、次に _id フィールドと movie_id フィールドの commentsコレクションと結合します。

db.movies.aggregate( [
{ $match: { runtime: { $gt: 1000 } } },
{
$lookup: {
from: "comments",
localField: "_id",
foreignField: "movie_id",
as: "movie_comments"
}
},
{
$project: {
_id: 0,
title: 1,
year: 1,
"movie_comments.name": 1,
"movie_comments.text": 1,
"movie_comments.date": 1
}
}
] )
[
{
title: 'Centennial',
year: 1978,
movie_comments: [
{
name: 'Ellaria Sand',
text: 'Excepturi nam nam eum possimus aspernatur autem. Quis nulla optio praesentium ut distinctio explicabo.',
date: ISODate('1995-08-18T03:01:50.000Z')
}
]
},
{ title: 'Baseball', year: 1994, movie_comments: [] }
]

この操作は、次の疑似 SQL ステートメントに対応します。

SELECT *, movie_comments
FROM movies
WHERE movie_comments IN (
SELECT *
FROM comments
WHERE movie_id = movies._id
);

詳細については、「等価一致のパフォーマンスに関する考慮事項」をご覧ください。

localFieldが配列の場合、$unwindステージを使用せずに、配列要素をスカラーforeignFieldと照合できます。

次の集計操作では、moviesコレクションと usersコレクションを結合し、moviescast 配列フィールドと users のスカラー nameフィールドを照合します。

db.movies.aggregate( [
{
$match: {
title: {
$in: [ "Roger & Me", "The Sum of Us",
"Centennial" ]
}
}
},
{
$lookup: {
from: "users",
localField: "cast",
foreignField: "name",
as: "cast_users"
}
},
{
$project: {
_id: 0,
title: 1,
year: 1,
cast: 1,
"cast_users.name": 1,
"cast_users.email": 1
}
},
{ $sort: { year: 1 } }
] )
[
{
cast: [
'Raymond Burr',
'Barbara Carrera',
'Richard Chamberlain',
'Robert Conrad'
],
title: 'Centennial',
year: 1978,
cast_users: []
},
{
cast: [
'Michael Moore',
'Roger B. Smith',
'Rhonda Britton',
'Fred Ross'
],
title: 'Roger & Me',
year: 1989,
cast_users: [ { name: 'Michael Moore', email: 'michael_moore@fakegmail.com' } ]
},
{
cast: [
'Jack Thompson',
'Russell Crowe',
'John Polson',
'Deborah Kennedy'
],
title: 'The Sum of Us',
year: 1994,
cast_users: [
{
name: 'Deborah Kennedy',
email: 'deborah_kennedy@fakegmail.com'
}
]
}
]

$mergeObjects 演算子は、複数のドキュメントを 1 つのドキュメントに結合します。

The following operation uses $lookup to join the movies collection with the comments collection, then uses $mergeObjects in $replaceRoot to merge the first comment document with the movie document:

db.movies.aggregate( [
{ $match: { runtime: { $gt: 1000 } } },
{
$lookup: {
from: "comments",
localField: "_id",
foreignField: "movie_id",
as: "movie_comments"
}
},
{
$replaceRoot: {
newRoot: {
$mergeObjects: [
{ $arrayElemAt: [ "$movie_comments", 0 ] },
"$$ROOT"
]
}
}
},
{
$project: {
_id: 0,
title: 1,
year: 1,
genres: 1,
name: 1,
email: 1,
text: 1,
date: 1
}
}
] )
[
{
name: 'Ellaria Sand',
email: 'indira_varma@gameofthron.es',
text: 'Excepturi nam nam eum possimus aspernatur autem. Quis nulla optio praesentium ut distinctio explicabo.',
date: ISODate('1995-08-18T03:01:50.000Z'),
genres: [ 'Action', 'Adventure', 'Drama' ],
title: 'Centennial',
year: 1978
},
{
genres: [ 'Documentary', 'History', 'Sport' ],
title: 'Baseball',
year: 1994
}
]

パイプラインは外部コレクションに対して実行でき、複数の結合条件を含めることができます。$expr 演算子を使用すると、接続詞や不等価一致など、より複雑な結合条件が可能になります。

結合条件は、aggregate()メソッドが実行されたローカル コレクション内のフィールドを参照し、外部コレクション内のフィールドを参照できます。これにより、2つのコレクション間の相関サブクエリが可能になります。

MongoDB 5.0 は簡潔な相関サブクエリをサポートしています。

次の例:

  • _id フィールドと movie_id フィールドを使用して movies コレクションと comments コレクションを結合します。

  • 映画の公開年後に投稿されたコメントのみを含めるようにコメントをフィルタリングします。

db.movies.aggregate( [
{
$match: {
title: {
$in: [ "Class Action", "Kafka", "Corpse Bride" ]
}
}
},
{
$lookup: {
from: "comments",
localField: "_id",
foreignField: "movie_id",
let: { movie_year: "$year" },
pipeline: [
{
$match: {
$expr: {
$gt: [
{ $year: "$date" }, "$$movie_year"
]
}
}
},
{ $project: { _id: 0, name: 1, date: 1 } }
],
as: "post_release_comments"
}
},
{
$project: {
_id: 0,
title: 1,
year: 1,
post_release_comments: 1
}
}
] )
[
{
year: 1991,
title: 'Class Action',
post_release_comments: [
{ name: 'Khal Drogo', date: ISODate('2016-12-06T07:17:03.000Z') }
]
},
{
year: 1991,
title: 'Kafka',
post_release_comments: [
{ name: 'Khal Drogo', date: ISODate('1998-05-10T03:10:20.000Z') }
]
},
{ year: 2005, title: 'Corpse Bride', post_release_comments: [] }
]

この操作は、次の疑似 SQL ステートメントに対応します。

SELECT *, post_release_comments
FROM movies
WHERE post_release_comments IN (
SELECT name, date
FROM comments
WHERE movie_id = movies._id
AND YEAR(date) > movies.year
);

The $eq, $lt, $lte, $gt, and $gte comparison operators placed in an $expr operator can use an index on the from collection referenced in a $lookup stage. Limitations:

  • インデックスはフィールドと定数の比較にのみ使用できるため、let オペランドは定数に変換する必要があります。

    たとえば、$a と定数値の比較にはインデックスを使用できますが、$a$b の比較には使用できません。

  • let オペランドが空の値または欠損値に変換される場合の比較には、インデックスは使用されません。

  • マルチキー部分、またはスパースインデックスは使用されません。

たとえば、インデックス{ movie_id: 1 } commentsコレクションに存在する場合:

  • comments.movie_idフィールドの等価一致はインデックスを使用します。

An aggregation pipeline $lookup stage can execute a pipeline on the foreign collection, which allows uncorrelated subqueries. An uncorrelated subquery does not reference the local document fields.

注意

Starting in MongoDB 5.0, for an uncorrelated subquery in a $lookup pipeline stage containing a $sample stage, the $sampleRate operator, or the $rand operator, the subquery is always run again if repeated. Previously, depending on the subquery output size, either the subquery output was cached or the subquery was run again.

次の操作では、moviesコレクションからの さらに 上映時間が 1000 分を超える映画と usersコレクションを結合します。

db.users.aggregate( [
{
$match: {
email: { $in: [
"mark_addy@gameofthron.es",
"lena_headey@gameofthron.es"
] }
}
},
{
$lookup: {
from: "movies",
pipeline: [
{ $match: { runtime: { $gt: 1000 } } },
{ $project: { _id: 0, title: 1, year: 1 } }
],
as: "long_movies"
}
},
{
$project: {
_id: 0, name: 1, email: 1, long_movies: 1
}
}
] )
[
{
name: 'Robert Baratheon',
email: 'mark_addy@gameofthron.es',
long_movies: [
{ title: 'Centennial', year: 1978 },
{ title: 'Baseball', year: 1994 }
]
},
{
name: 'Cersei Lannister',
email: 'lena_headey@gameofthron.es',
long_movies: [
{ title: 'Centennial', year: 1978 },
{ title: 'Baseball', year: 1994 }
]
}
]

この操作は、次の疑似 SQL ステートメントに対応します。

SELECT *, long_movies
FROM users
WHERE long_movies IN (
SELECT title, year
FROM movies
WHERE runtime > 1000
);

詳細については、「非相関サブクエリのパフォーマンスに関する検討事項」を参照してください。

バージョン 5.0 の新機能。

Starting in MongoDB 5.0, an aggregation pipeline $lookup stage supports a concise correlated subquery syntax that improves joins between collections. The new concise syntax removes the requirement for an equality match on the foreign and local fields inside of an $expr operator in a $match stage.

次の例:

  • Joins the movies and comments collections by matching the localField _id with the foreignField movie_id. The match is performed before the pipeline is run.

  • それぞれ $$movie_year$date を使用してアクセスされた、映画の公開年後に投稿されたもののみを含むようにコメントをフィルタリングします。

db.movies.aggregate( [
{
$match: {
title: { $in: [
"I Don't Kiss",
"Lucky Luke",
"Mississippi Masala"
] }
}
},
{
$lookup: {
from: "comments",
localField: "_id",
foreignField: "movie_id",
let: { movie_year: "$year" },
pipeline: [
{
$match: {
$expr: {
$gt: [
{ $year: "$date" }, "$$movie_year"
]
}
}
},
{ $project: { _id: 0, name: 1, date: 1 } }
],
as: "post_release_comments"
}
},
{
$project: {
_id: 0,
title: 1,
year: 1,
post_release_comments: 1
}
}
] )
[
{
title: "I Don't Kiss",
year: 1991,
post_release_comments: [
{
name: 'Brandon Hardy',
date: ISODate('2016-09-18T11:11:34.000Z')
}
]
},
{
title: 'Lucky Luke',
year: 1991,
post_release_comments: [
{
name: 'Kelsey Smith',
date: ISODate('2010-01-13T17:55:01.000Z')
}
]
},
{
title: 'Mississippi Masala',
year: 1991,
post_release_comments: [
{
name: 'Phillip Collins',
date: ISODate('2010-05-13T08:04:22.000Z')
}
]
}
]

この例では、MongoDB バージョン 5.0 以前の古い冗語構文を使用しており、以前の簡潔な例と同様の結果を返します。

db.movies.aggregate( [
{
$match: {
title: { $in: [
"I Don't Kiss",
"Lucky Luke",
"Mississippi Masala"
] }
}
},
{
$lookup: {
from: "comments",
let: { movie_id: "$_id", movie_year: "$year" },
pipeline: [
{
$match: {
$expr: {
$and: [
{ $eq: [ "$movie_id", "$$movie_id" ] },
{ $gt: [
{ $year: "$date" }, "$$movie_year"
] }
]
}
}
},
{ $project: { _id: 0, name: 1, date: 1 } }
],
as: "post_release_comments"
}
},
{
$project: {
_id: 0,
title: 1,
year: 1,
post_release_comments: 1
}
}
] )
[
{
title: "I Don't Kiss",
year: 1991,
post_release_comments: [
{
name: 'Brandon Hardy',
date: ISODate('2016-09-18T11:11:34.000Z')
}
]
},
{
title: 'Lucky Luke',
year: 1991,
post_release_comments: [
{
name: 'Kelsey Smith',
date: ISODate('2010-01-13T17:55:01.000Z')
}
]
},
{
title: 'Mississippi Masala',
year: 1991,
post_release_comments: [
{
name: 'Phillip Collins',
date: ISODate('2010-05-13T08:04:22.000Z')
}
]
}
]

前の例は、次の疑似 SQL ステートメントに対応します。

SELECT *, post_release_comments
FROM movies
WHERE post_release_comments IN (
SELECT *
FROM comments
WHERE comments.movie_id = movies._id
AND YEAR(comments.date) > movies.year
);

詳細については、「相関サブクエリのパフォーマンスに関する考慮事項」をご覧ください。

このページのC#の例では、Atlasサンプルデータセットsample_mflixデータベースを使用します。MongoDB Atlasクラスターを無料で作成して、サンプルデータセットをロードする方法については、 MongoDB .NET/ C#ドライバーのドキュメントの「 開始 」を参照してください。

次の Movie クラスは、sample_mflix.movies コレクション内のドキュメントをモデル化します。

[BsonIgnoreExtraElements]
public class Movie
{
[BsonId]
public ObjectId Id { get; set; }
[BsonElement("title")]
public string Title { get; set; } = null!;
[BsonElement("year")]
public int? Year { get; set; }
[BsonElement("runtime")]
public int? Runtime { get; set; }
[BsonElement("rated")]
public string? Rated { get; set; }
[BsonElement("metacritic")]
public int Metacritic { get; set; }
[BsonElement("plot")]
public string? Plot { get; set; }
[BsonElement("type")]
public string? Type { get; set; }
[BsonElement("cast")]
public string[]? Cast { get; set; }
[BsonElement("directors")]
public string[]? Directors { get; set; }
[BsonElement("writers")]
public string[]? Writers { get; set; }
[BsonElement("imdb")]
public ImdbData? Imdb { get; set; }
}

次の Comment クラスは、sample_mflix.comments コレクション内のドキュメントをモデル化します。

[BsonIgnoreExtraElements]
public class Comment
{
[BsonId]
public ObjectId Id { get; set; }
[BsonElement("movie_id")]
public ObjectId MovieId { get; set; }
[BsonElement("text")]
public string Text { get; set; } = null!;
}

次の LookupResult クラスには、$lookup ステージの出力が保存されます。

[BsonIgnoreExtraElements]
public class LookupResult
{
[BsonId]
public ObjectId Id { get; set; }
[BsonElement("title")]
public string Title { get; set; } = null!;
public List<Comment> Comments { get; set; } = [];
}

To use the MongoDB .NET/C# driver to add a $lookup stage to an aggregation pipeline, call the UnionWith() method on a PipelineDefinition object.

次の例では、movies コレクションと comments コレクション間で左外部結合を実行するパイプラインステージを作成します。このコードは、各 Movieドキュメントの IdフィールドをComment ドキュメントの MovieIdフィールドに結合します。各映画のコメントは、各 LookupResultドキュメントの Comments という名前のフィールドに保存されます。

var commentCollection = _client
.GetDatabase("sample_mflix")
.GetCollection<Comment>("comments");
var pipeline = new EmptyPipelineDefinition<Movie>()
.Lookup<Movie, Movie, Comment, LookupResult>(
foreignCollection: commentCollection,
localField: m => m.Id,
foreignField: c => c.MovieId,
@as: r => r.Comments);

このページのNode.js の例では、Atlasサンプルデータセットsample_mflixデータベースを使用します。無料のMongoDB Atlas cluster を作成し、サンプルデータセットをロードする方法については、 MongoDB Node.jsドライバーのドキュメントの開始を参照してください。

MongoDB Node.jsドライバーを使用して $lookup ステージを集計パイプラインに追加するには、パイプラインオブジェクトで $lookup 演算子を使用します。

次の例では、movies コレクションと comments コレクションの間で左外部結合を実行するパイプラインステージを作成します。このコードは、各 movie ドキュメントの _id フィールドを comment ドキュメントの movie_id フィールドに結合します。comments フィールドは、各 movie ドキュメントの各映画に対するコメントを保存します。次に、この例は集計パイプラインを実行します。

const pipeline = [
{
$lookup: {
from: "comments",
localField: "_id",
foreignField: "movie_id",
as: "comments"
}
}
];
const cursor = collection.aggregate(pipeline);
return cursor;