如何将集合子数组对象与其他集合中存在的实际对象聚合在一起?

例如:This is how my collections look like

Collection 1 - (Teams)

const Teams = [
    {
        _id: '60f3b0b3f0b9a1b0b4f9b1a1',
        teamName: 'World XI A',
        totalPlayers: 15,
        player: [
            {
                playerId: '60f3b0b3f0b9a1b0b4f9b1a2',
                playerName: 'Player A',
                score: 10,
            },
            {
                playerId: '60f3b0b3f0b9a1b0b4f9b1a3',
                playerName: 'Player B',
                score: 20,
            },
        ],
    },
    {
        _id: '60f3b0b3f0b9a1b0b4f9b1a4',
        teamName: 'Crackers',
        totalPlayers: 15,
        player: [
            {
                playerId: '60f3b0b3f0b9a1b0b4f9b1a5',
                playerName: 'Player C',
                score: 30,
            },
            {
                playerId: '60f3b0b3f0b9a1b0b4f9b1a6',
                playerName: 'Player D',
                score: 40,
            },
        ],
    },
];

Collection 2 - (Players)

const Players = [
    {
        _id: '60f3b0b3f0b9a1b0b4f9b1a2',
        playerName: 'Player A',
        rank: 2,
        totalRuns: 5000,
    },
    {
        _id: '60f3b0b3f0b9a1b0b4f9b1a3',
        playerName: 'Player B',
        rank: 1,
        totalRuns: 3050,
    },
    {
        _id: '60f3b0b3f0b9a1b0b4f9b1a5',
        playerName: 'Player C',
        rank: 3,
        totalRuns: 2050,
    },
    {
        _id: '60f3b0b3f0b9a1b0b4f9b1a6',
        playerName: 'Player D',
        rank: 4,
        totalRuns: 1000,
    },
];

结果:This is how the resultant array should look like

Resultant array

const result = [
    {
        _id: '60f3b0b3f0b9a1b0b4f9b1a1',
        teamName: 'World XI A',
        totalPlayers: 15,
        player: [
            {
                playerInfo: {
                    _id: '60f3b0b3f0b9a1b0b4f9b1a2',
                    playerName: 'Player A',
                    rank: 2,
                    totalRuns: 5000,
                },
                playerName: 'Player A',
                score: 10,
            },
            {
                playerInfo: {
                    _id: '60f3b0b3f0b9a1b0b4f9b1a3',
                    playerName: 'Player B',
                    rank: 1,
                    totalRuns: 3050,
                },
                playerName: 'Player B',
                score: 20,
            },
        ],
    },
    {
        _id: '60f3b0b3f0b9a1b0b4f9b1a4',
        teamName: 'Crackers',
        totalPlayers: 15,
        player: [
            {
                playerInfo: {
                    _id: '60f3b0b3f0b9a1b0b4f9b1a5',
                    playerName: 'Player C',
                    rank: 3,
                    totalRuns: 2050,
                },
                playerName: 'Player C',
                score: 30,
            },
            {
                playerInfo: {
                    _id: '60f3b0b3f0b9a1b0b4f9b1a6',
                    playerName: 'Player D',
                    rank: 4,
                    totalRuns: 1000,
                },
                playerName: 'Player D',
                score: 40,
            },
        ],
    },
];

推荐答案

  1. $lookup-将TeamsPlayers集合与字段联接.并返回players数组字段.

  2. $set-设置player字段.

    2.1.$map-迭代player数组中的元素并返回新array.

    2.1.1.$mergeObjects-将当前迭代文档与结果2.1.1.1中具有playerInfo字段的文档合并.

    2.1.1.1.$first-从结果2.1.1.1.1中获取第一个匹配的文档.

    2.1.1.1.1.$filter-筛选players数组中与_id匹配的文档.

  3. $unset-删除字段:players字段和player.playerId字段.

db.Teams.aggregate([
  {
    "$lookup": {
      "from": "Players",
      "localField": "player.playerId",
      "foreignField": "_id",
      "as": "players"
    }
  },
  {
    $set: {
      player: {
        $map: {
          input: "$player",
          as: "p",
          in: {
            $mergeObjects: [
              "$$p",
              {
                playerInfo: {
                  $first: {
                    $filter: {
                      input: "$players",
                      cond: {
                        $eq: [
                          "$$p.playerId",
                          "$$this._id"
                        ]
                      }
                    }
                  }
                }
              }
            ]
          }
        }
      }
    }
  },
  {
    $unset: [
      "players",
      "player.playerId"
    ]
  }
])

Demo @ Mongo Playground

Javascript相关问答推荐

如何制作删除按钮以从列表中删除该项目所属的项目?

如何在不使用类型化数组的情况下将32位浮点数按位转换为整值?

JS、C++和C#给出不同的Base 64 Guid编码结果

如何通过在提交时工作的函数显示dom元素?

D3多线图显示1线而不是3线

为什么我的includes声明需要整个字符串?

Angular:动画不启动

Snowflake JavaScript存储过程返回成功,尽管预期失败

colored颜色 检测JS,平均图像 colored颜色 检测JS

jQuery s data()[storage object]在vanilla JavaScript中?'

手机上的渲染错误文本必须在文本组件中渲染,但在浏览器上没有问题<><>

如何调用名称在字符串中的实例方法?

如何从Intl.DateTimeFormat中仅获取时区名称?

如何使用子字符串在数组中搜索重复项

try 使用PM2在AWS ubuntu服务器上运行 node 进程时出错

从逗号和破折号分隔的给定字符串中查找所有有效的星期几

是否可以在不更改组件标识的情况下换出Reaction组件定义(以维护状态/引用等)?如果是这样的话,是如何做到的呢?

JavaScript将字符串数字转换为整数

谷歌饼图3D切片

连续添加promise 时,如何在所有promise 都已结算时解除加载覆盖