从集合中选择所有字段,按最低字段值排序,按不同字段“分组”?

时间:2019-06-02 22:46:21

标签: mongodb mongoose

我有一个集合scores,其中包含以下字段

┬────────┬───────┬──────────┐
│ player │ score │   mode   │
┼────────┼───────┼──────────┤
│  'A'   │   7   │  'easy'  │
│  'A'   │  11   │ 'medium' │
│  'A'   │  12   │  'hard'  │
│  'B'   │   9   │  'hard'  │
│  'B'   │  10   │  'easy'  │
│  'B'   │  10   │ 'medium' │
│  'C'   │   6   │ 'medium' │
│  'C'   │   9   │  'easy'  │
│  'C'   │  13   │  'hard'  │
┴────────┴───────┴──────────┘

我想选择所有得分最低的by player,因此预期结果将是:

┬────────┬───────┬──────────┐
│ player │ score │   mode   │
┼────────┼───────┼──────────┤
│  'A'   │   7   │  'easy'  │
│  'B'   │   9   │  'hard'  │
│  'C'   │   6   │ 'medium' │
┴────────┴───────┴──────────┘

此外,我想保留文档的原始结构,以便将预期结果加载为猫鼬对象。

1 个答案:

答案 0 :(得分:0)

您可以使用聚合框架执行以下操作:

  1. $sort收集玩家的分数,然后是得分
  2. 使用$group阶段按玩家分组,并在每组上抓取$first条目
  3. $project为必要的输出格式
  4. (可选)在播放器上$sort

例如,这是基于您的示例的集合:

> db.test.find()
{ "_id": 2, "player": "A", "score": 12, "mode": "hard" }
{ "_id": 0, "player": "A", "score": 7, "mode": "easy" }
{ "_id": 1, "player": "A", "score": 11, "mode": "medium" }
{ "_id": 3, "player": "B", "score": 9, "mode": "hard" }
{ "_id": 4, "player": "B", "score": 10, "mode": "easy" }
{ "_id": 5, "player": "B", "score": 10, "mode": "medium" }
{ "_id": 6, "player": "C", "score": 6, "mode": "medium" }
{ "_id": 7, "player": "C", "score": 9, "mode": "easy" }
{ "_id": 8, "player": "C", "score": 13, "mode": "hard" }

使用上述工作流程进行汇总:

db.test.aggregate([

  {$sort: {player: 1, score: 1}},

  {$group: { _id: '$player', 
             player: {$first:'$player'},
             score: {$first:'$score'}, 
             mode: {$first:'$mode'} }},

  {$project: { _id: 0 }},

  {$sort: {player: 1}}

])

输出为:

{ "player": "A", "score": 7, "mode": "easy" }
{ "player": "B", "score": 9, "mode": "hard" }
{ "player": "C", "score": 6, "mode": "medium" }

如果收藏量很大,请确保您有一个index,规格为{player: 1, score: 1}