猫鼬按字段排序嵌套数组

时间:2020-04-05 17:25:16

标签: mongodb mongoose aggregation-framework

我有一个GameStatistics集合,我想按他们的得分对所有玩家DESC进行排序。

所有玩家在带有嵌套游戏的activePlayers数组中列出。每个玩家都有一个points字段(我在下面放置了代码和架构)。

似乎我缺少了一些东西,我已经尝试过使用aggregate(),但是也没有运气。

sort = async (req: Request, res: Response, next: NextFunction) => {
  const id = "0021900805";
  const stats = await GameStats.findById(id)
    .sort({ "vTeam.activePlayers.points": -1 })
    .exec();
  return res.status(200).json(stats);
};

该集合如下所示:

[
  {
    "vTeam": {
      "activePlayers": [
        {
          "teamId": "1610612759",
          "firstName": "Lonnie",
          "lastName": "Walker IV",
          "points": "23",
          "assists": "0",
          "rebounds": "4",
          "fgp": "40.0",
          "to": "0",
          "stl": "3",
          "blk": "0"
        },
        {
          "teamId": "1610612759",
          "firstName": "LaMarcus",
          "lastName": "Aldridge",
          "points": "4",
          "assists": "3",
          "rebounds": "14",
          "fgp": "45.0",
          "to": "2",
          "stl": "1",
          "blk": "1"
        }
      ]
    },
    "_id": "0021900805",
    "createdAt": "2020-04-05T15:34:26.457Z",
    "vTeamScore": "114"
  }
]

2 个答案:

答案 0 :(得分:2)

您可以使用mongodb聚合框架来解决此问题。

Playground

sort = async (req: Request, res: Response, next: NextFunction) => {
  const id = "0021900805";
  const stats = await GameStats.aggregate([
    {
      $match: {
        _id: id, // or mongoose.Types.ObjectId(id)
      },
    },
    {
      $unwind: "$vTeam.activePlayers",
    },
    {
      $sort: {
        "vTeam.activePlayers.points": -1,
      },
    },
    {
      $group: {
        _id: "$_id",
        activePlayers: {
          $push: "$vTeam.activePlayers",
        },
        doc: {
          $first: "$$ROOT",
        },
      },
    },
    {
      $replaceRoot: {
        newRoot: {
          $mergeObjects: [
            "$doc",
            {
              vTeamActivePlayers: "$activePlayers",
            },
          ],
        },
      },
    },
    {
      $addFields: {
        "vTeam.activePlayers": "$vTeamActivePlayers",
      },
    },
    {
      $project: {
        vTeamActivePlayers: 0,
      },
    },
  ]);

  return res.status(200).json(stats);
};

答案 1 :(得分:0)

根据mongoose's docs,您的解决方案是将1替换为-1

所以:const stats = await GameStats.findById(id).sort({'vTeam.activePlayers.points': -1}).exec();