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:管理者