【问题标题】:Join two collections in MongoDB by merging properties from one into the other通过将属性从一个合并到另一个来加入 MongoDB 中的两个集合
【发布时间】:2021-06-16 02:21:38
【问题描述】:

我需要帮助加入 MongoDB 中的两个集合。

我有两个系列:卡片和套牌。我需要加入它们,以便在卡片组文档中拥有卡片文档的属性。下面是每个集合的两个 JSON 格式的示例:

  1. 甲板

例子:

{
    "_id": {
        "$oid": "608edd53a8220000b2000882"
    },
    "name": "Izzet Phoenix",
    "cards": {
        "mainboard": [
            {
                "qty": "4",
                "name": "Arclight Phoenix",
                "id": "787de9ce-02c5-4a17-a88b-d38e83dbeb0b"
            },
            ... a bunch of other cards in the same format (qty, name, id)
        ],
        "sideboard": [
            {
                "qty": "2",
                "name": "Abrade",
                "id": "84319dfb-eaf7-4b98-8c4f-30f5e779591b"
            },
            ... a bunch of other cards in the same format (qty, name, id)
        ]
    },
    ... a bunch of other properties of the deck
}
  1. 卡片

例子:

{
    "_id": {
        "$oid": "608b60d6a40a0000c9017853"
    },
    "name": "Abrade",
    "id": "84319dfb-eaf7-4b98-8c4f-30f5e779591b",
    ... a bunch of other properties of the card
}

请注意,decks 集合使用卡片的“id”字段作为参考,而不是“_id”字段。

这是我正在寻找的期望输出:

{
    "_id": {
        "$oid": "608edd53a8220000b2000882"
    },
    "name": "Izzet Phoenix",
    "cards": {
        "mainboard": [
            {
                "qty": "4",
                "name": "Arclight Phoenix",
                "id": "787de9ce-02c5-4a17-a88b-d38e83dbeb0b",
                ... add properties of the card Arclight Phoenix, with id = 787de9ce-02c5-4a17-a88b-d38e83dbeb0b
            },
            ... a bunch of other cards
        ],
        "sideboard": [
            {
                "qty": "2",
                "name": "Abrade",
                "id": "84319dfb-eaf7-4b98-8c4f-30f5e779591b",
                ... add properties of the card Abrade, with id 84319dfb-eaf7-4b98-8c4f-30f5e779591b
            },
            ... a bunch of other cards
        ]
    },
    ... a bunch of other properties of the deck
}

我尝试研究如何解决这个问题,我发现 MongoDB 有一个 $lookup 阶段,但我不熟悉管道和阶段的概念,这最终让我望而却步。

感谢所有帮助。

感谢您的宝贵时间!

【问题讨论】:

    标签: mongodb


    【解决方案1】:

    我能够通过混合使用 $unwind、$lookup、$addFields、$group 和 $project 来解决这个问题。

    最终管道:

    db.getCollection("decks").aggregate(
        // Pipeline
        [
            // Stage 1
            {
                $match: {
                    "_id": ObjectId("608edd53a8220000b2000882")
                }
            },
            // Stage 2
            {
                $unwind: {
                    path: "$cards.mainboard"
                }
            },
            // Stage 3
            {
                $lookup: {
                    from: "cards",
                    localField: "cards.mainboard.id",
                    foreignField: "id",
                    as: "cards.mainboard.card"
                }
            },
            // Stage 4
            {
                $unwind: {
                    path: "$cards.mainboard.card"
                }
            },
            // Stage 5
            {
                $addFields: {
                    "cards.mainboard": {
                        "$mergeObjects": ["$cards.mainboard.card", "$cards.mainboard"]
                    }
                }
            },
            // Stage 6
            {
                $group: {
                    _id: "$_id",
                    "name": { "$first": "$name" },
                    "cards": { "$first": "$cards" },
                    "mainboardCards": { "$push": "$cards.mainboard" },
                }
            },
            // Stage 7
            {
                $project: {
                    "mainboardCards.card": 0
                }
            },
            // Stage 8
            {
                $unwind: {
                    path: "$cards.sideboard"
                }
            },
            // Stage 9
            {
                $lookup: {
                    from: "cards",
                    localField: "cards.sideboard.id",
                    foreignField: "id",
                    as: "cards.sideboard.card"
                }
            },
            // Stage 10
            {
                $unwind: {
                    path: "$cards.sideboard.card"
                }
            },
            // Stage 11
            {
                $addFields: {
                    "cards.sideboard": {
                        "$mergeObjects": ["$cards.sideboard.card", "$cards.sideboard"]
                    }
                }
            },
            // Stage 12
            {
                $group: {
                    _id: "$_id",
                    "name": { "$first": "$name" },
                    "mainboardCards": { "$first": "$mainboardCards" },
                    "sideboardCards": { "$push": "$cards.sideboard" },
                }
            },
            // Stage 13
            {
                $project: {
                    "sideboardCards.card": 0
                }
            },
        ],
    );
    

    【讨论】:

      猜你喜欢
      • 2019-10-01
      • 2015-09-14
      • 2023-04-04
      • 2015-01-18
      • 1970-01-01
      • 2015-11-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-31
      相关资源
      最近更新 更多