MongoDB を使用して 2つのコレクションを 1つのコレクションに結合する
- MongoDB を使用して、2つのコレクションを 1つのコレクションに結合する
-
$lookup集計ステージを使用して、2つのコレクションを 1つに結合する -
pipeline演算子を使用して、指定された条件に基づいて 2つのコレクションを 1つに結合する -
結果のドキュメントに添付する前に、
$unwind演算子を使用してフラットアレイにする -
集計クエリの
$projectフィルタステージを使用して、2つのコレクションを 1つに結合する - Compass(MongoDB のグラフィカルインターフェイス)を使用して 2つのコレクションに参加する
今日は、$lookup 集計ステージ、pipeline および $unwind 演算子、$project フィルターステージ、および MongoDB Compass を使用して、2つのコレクションを 1つのコレクションに結合します。
MongoDB を使用して、2つのコレクションを 1つのコレクションに結合する
MongoDB を使用して、2つのコレクションを 1つのコレクションに結合するためのさまざまなアプローチがあります。それらのいくつかを以下に示します。これについては、このチュートリアルで説明します。
$lookup集計ステージを使用して、2つのコレクションを結合しますpipeline演算子を使用して、指定された条件に基づいて 2つのコレクションを結合します$unwind演算子を使用して、結果のドキュメントに添付する前にアレイをフラット化します- 集計クエリで
$projectフィルターステージを使用して、2つのコレクションを結合します - コンパス(MongoDB のグラフィカルインターフェイス)を使用して 2つのコレクションを結合します
上記のすべてのシナリオでは、ドキュメント(MySQL のレコードと同じ)が入力された 2つのコレクション(MySQL のテーブルと同じ)を含むデータベースが必要です。次のクエリを使用してこれを実行しました。あなたもそうすることができます。
users データベースに存在する usersInformation と userAddress という名前の 2つのコレクションを作成します。さらに、次のようにドキュメントを入力します。
データベースとコレクションを作成します。
> use users
> db.createCollection('userInformation')
> db.createCollection('userAddress')
userInformation コレクションに 2つのドキュメントを入力します。
> db.userInformation.insertMany(
[
{
fullname: 'Mehvish Ashiq',
age: 30,
gender: 'Female',
nationality: 'Pakistani'
},
{
fullname: 'James Daniel',
age: 45,
sex: 'male',
nationality: 'Canadian'
}
]
)
userAddress コレクションに 2つのドキュメントを入力します。
> db.userAddress.insertMany(
[
{
fullname: 'Mehvish Ashiq',
block_number: 22,
street: 'Johar Town Street',
city: 'Lahore'
},
{
fullname: 'James Daniel',
block_number: 30,
street: 'Saint-Denis Street',
city: 'Montreal'
}
]
)
insertMany() 関数を使用して、複数のドキュメントを挿入します。これで、以下のコマンドを使用して、両方のコレクションのデータを確認できます。
次のコードスニペットでは、pretty() メソッドがクリーンでフォーマットされた出力を示しています。これはシェルで簡単に理解できます。
userInformation からのドキュメントを表示します。
> db.userInformation.find().pretty()
出力:
{
"_id" : ObjectId("628bc4a45c544feccff5a566"),
"fullname" : "Mehvish Ashiq",
"age" : 30,
"gender" : "Female",
"nationality" : "Pakistani"
}
{
"_id" : ObjectId("628bc4a45c544feccff5a567"),
"fullname" : "James Daniel",
"age" : 45,
"sex" : "male",
"nationality" : "Canadian"
}
userAddress からドキュメントを表示します。
> db.userAddress.find().pretty()
出力:
{
"_id" : ObjectId("628bc4ae5c544feccff5a568"),
"fullname" : "Mehvish Ashiq",
"block_number" : 22,
"street" : "Johar Town Street",
"city" : "Lahore"
}
{
"_id" : ObjectId("628bc4ae5c544feccff5a569"),
"fullname" : "James Daniel",
"block_number" : 30,
"street" : "Saint-Denis Street",
"city" : "Montreal"
}
$lookup 集計ステージを使用するには、両方のコレクションが同じデータベースに存在する必要があります。両方のコレクションの準備ができたら、さまざまなクエリを使用して、シナリオに応じて両方のコレクションのデータを結合できます。
$lookup 集計ステージを使用して、2つのコレクションを 1つに結合する
サンプルコード:
> db.userInformation.aggregate([
{ $lookup:
{
from: 'userAddress',
localField: 'fullname',
foreignField: 'fullname',
as: 'address'
}
}
]).pretty();
出力:
{
"_id" : ObjectId("628bc4a45c544feccff5a566"),
"fullname" : "Mehvish Ashiq",
"age" : 30,
"gender" : "Female",
"nationality" : "Pakistani",
"address" : [
{
"_id" : ObjectId("628bc4ae5c544feccff5a568"),
"fullname" : "Mehvish Ashiq",
"block_number" : 22,
"street" : "Johar Town Street",
"city" : "Lahore"
}
]
}
{
"_id" : ObjectId("628bc4a45c544feccff5a567"),
"fullname" : "James Daniel",
"age" : 45,
"sex" : "male",
"nationality" : "Canadian",
"address" : [
{
"_id" : ObjectId("628bc4ae5c544feccff5a569"),
"fullname" : "James Daniel",
"block_number" : 30,
"street" : "Saint-Denis Street",
"city" : "Montreal"
}
]
}
MongoDB データベースでは、$lookupaggregate stageが他のコレクションとの左外部結合を実行し、結合されたドキュメントから情報(データ)をフィルタリングします。たとえば、クエリを使用して、すべてのユーザーの情報とそのアドレスを取得します。
$lookup 関数は 4つのフィールドを受け入れます。最初は from フィールドで、他のコレクションと結合されることになっているコレクションを指定します。
2 番目は localField フィールドです。これは、from フィールドで指定されたコレクションの入力ドキュメントの属性(フィールド)の 1つです。
これは、コレクションのドキュメントから localField から foreignField への照合を実行するために使用されます。
同様に、foreignField という名前の 3 番目のフィールドも、コレクションのドキュメントから foreignField から localField への等価一致を実行します。
4 番目のフィールド as に新しいアレイの名前を書き込みます。 $lookup 集計ステージについては、次の説明を参照してください。

pipeline 演算子を使用して、指定された条件に基づいて 2つのコレクションを 1つに結合する
サンプルコード:
> db.userInformation.aggregate([{
$lookup:{
from: 'userAddress',
let: {full_name: '$fullname'},
pipeline: [{
$match: {
$expr: {
$eq: ['$fullname', '$$full_name']
}
}
}],
as: 'addressInfo'
}
}]).pretty()
出力:
{
"_id" : ObjectId("628bc4a45c544feccff5a566"),
"fullname" : "Mehvish Ashiq",
"age" : 30,
"gender" : "Female",
"nationality" : "Pakistani",
"addressInfo" : [
{
"_id" : ObjectId("628bc4ae5c544feccff5a568"),
"fullname" : "Mehvish Ashiq",
"block_number" : 22,
"street" : "Johar Town Street",
"city" : "Lahore"
}
]
}
{
"_id" : ObjectId("628bc4a45c544feccff5a567"),
"fullname" : "James Daniel",
"age" : 45,
"sex" : "male",
"nationality" : "Canadian",
"addressInfo" : [
{
"_id" : ObjectId("628bc4ae5c544feccff5a569"),
"fullname" : "James Daniel",
"block_number" : 30,
"street" : "Saint-Denis Street",
"city" : "Montreal"
}
]
}
特定の条件に基づいて 2つのコレクションを結合する場合(MySQL で WHERE 句を使用するのと同じように)、$lookup で pipeline 演算子を使用できます。
たとえば、userAddress の fullname が userInformation の fullname と等しいコレクションに参加しています。
結果のドキュメントに添付する前に、$unwind 演算子を使用してフラットアレイにする
サンプルコード:
> db.userInformation.aggregate([
{ $lookup:
{
from: 'userAddress',
localField: 'fullname',
foreignField: 'fullname',
as: 'address'
}
},
{
$unwind: '$address'
}
]).pretty();
出力:
{
"_id" : ObjectId("628bc4a45c544feccff5a566"),
"fullname" : "Mehvish Ashiq",
"age" : 30,
"gender" : "Female",
"nationality" : "Pakistani",
"address" : {
"_id" : ObjectId("628bc4ae5c544feccff5a568"),
"fullname" : "Mehvish Ashiq",
"block_number" : 22,
"street" : "Johar Town Street",
"city" : "Lahore"
}
}
{
"_id" : ObjectId("628bc4a45c544feccff5a567"),
"fullname" : "James Daniel",
"age" : 45,
"sex" : "male",
"nationality" : "Canadian",
"address" : {
"_id" : ObjectId("628bc4ae5c544feccff5a569"),
"fullname" : "James Daniel",
"block_number" : 30,
"street" : "Saint-Denis Street",
"city" : "Montreal"
}
}
$unwind 演算子は、結果のドキュメントにアタッチする前に、アレイをフラット化するだけです。 $unwind 演算子の基本的な違いは、単一の要素を持つ配列を、要素自体であるフラット化されたオブジェクトに変換することです。
この要素の名前は変更されないことに注意してください。これは、要素が配列の形式であった場合と同じになります。
$unwind 演算子を使用して、または使用せずに上記のクエリを実行し、address フィールドを確認します。
集計クエリの $project フィルタステージを使用して、2つのコレクションを 1つに結合する
$project を使用してコレクションに参加する前に、その重要性を理解しましょう。たとえば、userAddress という名前のコレクション全体を userInformation に結合したくない場合は、city フィールドと street フィールドのみを結合する必要があります。
その場合、$addFields ステージを使用する必要があります。このステージを使用して、任意のフィールドまたは複数のフィールドをアレイ/オブジェクトからドキュメントのルートレベルに結合/割り当てます。
したがって、次のクエリを実行して、userAddress コレクションから city と street を取得します。
サンプルコード:
> db.userInformation.aggregate([
{ $lookup:
{
from: 'userAddress',
localField: 'fullname',
foreignField: 'fullname',
as: 'address'
}
},
{
$unwind: '$address'
},
{
$addFields: {
street: '$address.street',
city: '$address.city'
}
}
]).pretty();
出力:
{
"_id" : ObjectId("628bc4a45c544feccff5a566"),
"fullname" : "Mehvish Ashiq",
"age" : 30,
"gender" : "Female",
"nationality" : "Pakistani",
"address" : {
"_id" : ObjectId("628bc4ae5c544feccff5a568"),
"fullname" : "Mehvish Ashiq",
"block_number" : 22,
"street" : "Johar Town Street",
"city" : "Lahore"
},
"street" : "Johar Town Street",
"city" : "Lahore"
}
{
"_id" : ObjectId("628bc4a45c544feccff5a567"),
"fullname" : "James Daniel",
"age" : 45,
"sex" : "male",
"nationality" : "Canadian",
"address" : {
"_id" : ObjectId("628bc4ae5c544feccff5a569"),
"fullname" : "James Daniel",
"block_number" : 30,
"street" : "Saint-Denis Street",
"city" : "Montreal"
},
"street" : "Saint-Denis Street",
"city" : "Montreal"
}
上記の出力に注意深く焦点を合わせます。通りと都市を取得していますか?はい、ドキュメントのルートレベルで street と city を取得していますが、現在必要のない address オブジェクトもあります。
ここで、$project フィルターステージが登場します。結果のドキュメントに含める必要のあるフィールドを指定します。
理解を深めるには、次のクエリを参照してください。
サンプルコード:
> db.userInformation.aggregate([
{ $lookup:
{
from: 'userAddress',
localField: 'fullname',
foreignField: 'fullname',
as: 'address'
}
},
{
$unwind: '$address'
},
{
$addFields: {
street: '$address.street',
city: '$address.city'
}
},
{
$project: {
fullname: 1,
age: 1,
gender: 1,
street: 1,
city: 1
}
}
]).pretty();
出力:
{
"_id" : ObjectId("628bc4a45c544feccff5a566"),
"fullname" : "Mehvish Ashiq",
"age" : 30,
"gender" : "Female",
"street" : "Johar Town Street",
"city" : "Lahore"
}
{
"_id" : ObjectId("628bc4a45c544feccff5a567"),
"fullname" : "James Daniel",
"age" : 45,
"street" : "Saint-Denis Street",
"city" : "Montreal"
}
ご覧のとおり、現在 address オブジェクトはありませんが、その 2つのフィールド(street と city)がドキュメントのルートレベルに割り当てられています。
Compass(MongoDB のグラフィカルインターフェイス)を使用して 2つのコレクションに参加する
グラフィカルインターフェイスを使用した集計は簡単です。 $lookup 集計段階では、次の手順に従うだけで済みます。
MongoDBCompassを開き、サーバーに接続します。- 必要に応じて、新しいデータベースと 2つのコレクションを作成します。Mongo シェルを使用して作成したものと同じデータベースとコレクションを使用します。
- 次のように表示されるコレクションを開きます。

-
プロジェクトの要件に従ってステージを追加します。
$lookup集計ステージを追加します。$lookupフィールドを更新して、右側に目的の結果を確認してください。
関連記事 - MongoDB Collection
- MongoDB Truncate コレクション
- MongoDB コレクション内のすべてのドキュメントに新しいフィールドを追加する
- MongoDB でのコレクションのドロップまたは削除
- NodeJS を使用して MongoDB にコレクションが存在するかどうかを確認する
- MongoDB の同じデータベース内のコレクションをコピーする
