
MongoDBのAggregation Frameworkを使用して、Node.jsで複数のコレクションを結合(JOIN)する方法を理解することで、より複雑なデータ操作が可能になり、データ分析や集計において高度な柔軟性を得ることができます。
今回は、Node.jsとMongoDBを使用して、ある2つのコレクションをLookUpで結合し、指定された出力内容を得る方法を、サンプルのソースコードと共にご紹介します。
基本的な接続
始める前に、MongoDBサーバーを起動し、適切なURIに接続情報を更新してください。
また、データベース名とコレクション名を適切なものに置き換えましょう。
const { MongoClient } = require('mongodb');
async function main() {
const uri = 'mongodb://localhost:27017'; // MongoDBの接続URI
const client = new MongoClient(uri);
try {
await client.connect();
const database = client.db('blog'); // データベース名を指定
const postCollection = database.collection('post');
const userCollection = database.collection('user');
// ... (ここにpostとuserコレクションを結合するコードを書く)
} finally {
await client.close();
}
}
main().catch(console.error);
コレクション構造(サンプル)
本記事のソースコードでは、post と user の2つのコレクションが使用します。
以下に、それぞれのコレクションの簡単な構造を示します。
post (投稿)コレクションの構造
post コレクションには、ユーザーID(user_id)が含まれており、このフィールドが user コレクションとの結合に使用されます。
{
"_id": ObjectId("..."),
"user_id": ObjectId("..."), // userコレクションとの結合キー
"create_dt": ISODate("..."), // 投稿作成日時
// その他の投稿に関するフィールド
}
user ユーザーコレクションの構造
user コレクションには、ユーザーに関する情報が含まれています。_idは post コレクションのユーザーID(user_id)と関連付けられます。
{
"_id": ObjectId("..."),
"user_name": "ユーザー名",
// その他のユーザーに関するフィールド
}
結合に使用されているフィールドは user_id であり、これによって post コレクションの各投稿が対応するユーザーの情報を取得できるようになっています。
データ結合
以下は、基本的なデータ結合の例です。
このコードは、投稿(post)とユーザー(user)の情報を結合して取得します。
const aggregationPipeline = [
{
$lookup: {
from: 'user',
localField: 'user_id',
foreignField: '_id',
as: 'user_info'
}
},
{
$unwind: '$user_info'
},
{
$project: {
post_create_dt: '$create_dt',
user_user_name: '$user_info.user_name'
}
}
];
const result = await postCollection.aggregate(aggregationPipeline).toArray();
console.log(result);
【おまけ】結合して検索する
特定の条件でデータを取得する場合、例えば「user_id」に基づいてデータを絞り込む場合は、以下のようにコードを変更します。
const specificUserId = ObjectId('1234567890abcdef12345678'); // 取得したいユーザーのIDを指定
const aggregationPipeline = [
{
$match: { user_id: specificUserId }
},
{
$lookup: {
from: 'users',
localField: 'user_id',
foreignField: '_id',
as: 'user_info'
}
},
{
$unwind: '$user_info'
},
{
$project: {
post_create_dt: '$create_dt',
user_user_name: '$user_info.user_name'
}
}
];
const result = await postCollection.aggregate(aggregationPipeline).toArray();
console.log(result);
上記のコードでは、 $match ステージを追加して指定した user_id に一致する投稿をフィルタリングしています。
それ以外の部分は前のコードと同様です。
必要ならば、検索対象の user_id を適切に指定してください。
まとめ
最後に、今回作成したサンプルコードの完成形を記述しておきます。
const { MongoClient } = require('mongodb');
async function main() {
const uri = 'mongodb://localhost:27017'; // MongoDBの接続URI
const client = new MongoClient(uri);
try {
await client.connect();
const database = client.db('blog'); // データベース名を指定
const postCollection = database.collection('post');
const userCollection = database.collection('user');
const specificUserId = ObjectId('1234567890abcdef12345678'); // 取得したいユーザーのIDを指定
const aggregationPipeline = [
{
$match: { user_id: specificUserId }
},
{
$lookup: {
from: 'user',
localField: 'user_id',
foreignField: '_id',
as: 'user_info'
}
},
{
$unwind: '$user_info'
},
{
$project: {
post_create_dt: '$create_dt',
user_user_name: '$user_info.user_name'
}
}
];
const result = await postCollection.aggregate(aggregationPipeline).toArray();
console.log(result);
} finally {
await client.close();
}
}
main().catch(console.error);
MongoDBのAggregation Frameworkを使ったデータ結合は、複雑なデータ処理を柔軟かつ効果的に行うための強力な手段です。
データの再利用性が向上し、冗長性を減少させます。
一方、大量のデータになるとパフォーマンスに影響が出る可能性があるため、適切なインデックスを利用しましょう。
結合の深さが深く(多重結合)なると理解や管理が難しくなります。
適切な設計と最適なクエリを構築することで、データの有効活用が可能となります。
- Original:https://minory.org/mongodb-join.html
- Source:minory
- Author:管理者