Node.jsでMongoDBのコレクションを結合(JOIN)して取得する

MongoDBAggregation Frameworkを使用して、Node.jsで複数のコレクション結合JOIN)する方法を理解することで、より複雑なデータ操作が可能になり、データ分析や集計において高度な柔軟性を得ることができます。
今回は、Node.jsMongoDBを使用して、ある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);

このコードは基本的な例であり、実際の環境に合わせて適宜調整が必要です。
必要に応じてエラーハンドリングやセキュリティ対策を追加してください。

コレクション構造(サンプル)

本記事のソースコードでは、postuser の2つのコレクションが使用します。
以下に、それぞれのコレクションの簡単な構造を示します。

post (投稿)コレクションの構造

post コレクションには、ユーザーID(user_id)が含まれており、このフィールドuser コレクションとの結合に使用されます。

{
    "_id": ObjectId("..."),
    "user_id": ObjectId("..."), // userコレクションとの結合キー
    "create_dt": ISODate("..."), // 投稿作成日時
    // その他の投稿に関するフィールド
}

user ユーザーコレクションの構造

user コレクションには、ユーザーに関する情報が含まれています。
_idpost コレクションのユーザー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);

MongoDBAggregation Frameworkを使ったデータ結合は、複雑なデータ処理を柔軟かつ効果的に行うための強力な手段です。
データの再利用性が向上し、冗長性を減少させます。

一方、大量のデータになるとパフォーマンスに影響が出る可能性があるため、適切なインデックスを利用しましょう。
結合の深さが深く(多重結合)なると理解や管理が難しくなります。

適切な設計と最適なクエリを構築することで、データの有効活用が可能となります。

著:目黒 聖
¥2,200 (2024/01/03 20:46時点 | Amazon調べ)
\楽天ポイント4倍セール!/
楽天市場
著:伊藤 康太
¥3,212 (2024/01/09 10:17時点 | Amazon調べ)
\楽天ポイント4倍セール!/
楽天市場


Amazonベストセラー

返信を残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA