【问题标题】:Sorting and ranking matching elements in a nested array list in MongoDB在 MongoDB 中对嵌套数组列表中的匹配元素进行排序和排名
【发布时间】:2021-04-07 19:34:27
【问题描述】:

向 MongoDB 的粉丝们问好!

我这里有一个包含棋盘游戏数据的数据结构,其中所获得的分数(每轮之后)被跟踪为与玩家姓名相关联的嵌套数组。请注意,每个棋盘游戏都有一组不同的玩家:

{
"BoardGames" : {
    "Game1" : {
        "players" : {
            "Anne" : [97, 165, 101, 67],
            "Pete" : [86, 115, 134, 149],
            "Scott" : [66, 89, 103, 74],
            "Jane" : [113, 144, 125, 99],
            "Katie" : [127, 108, 98, 151]
        }
    },
    "Game2" : {
        "players" : {
            "Margot" : [1, 0, 0, 0],
            "Pete" : [0, 0, 1, 1],
            "Michael" : [0, 0, 0, 0],
            "Jane" : [0, 0, 1, 0]
        }
    },
    "Game3" : {
        "players" : {
            "Chris" : [6, 2, 4, 0, 5, 7],
            "Pete" : [4, 5, 2, 5, 3, 1, 4],
            "Julia" : [3, 7, 4, 0],
            "Tom" : [3, 2, 4, 8, 2, 6, 7]
        }
    },
}
  • 游戏 1:玩家每轮尽可能多地获得胜利分数
  • 第二局:赢一局得1,输一局0
  • Game3:玩家可能会在每一轮结束后离开,因此有些玩家的游戏轮数比其他玩家多,因此这些数组的长度不同

所以,这是我的问题:

  1. 哪位玩家在每场比赛中得分最高?谁最少?
  2. 谁是第一轮的获胜者?第二轮等。
  3. 谁在所有玩过的游戏中排名第一、第二和第三?

我已经用 mongo 完成了一些查询,但到目前为止,我不知道如何编写查询。此外,也许这不是我构建数据的最佳方式。所以如果你有更好的主意,我很乐意学习!

干杯!

P.S.:以上 JSON 数据的 insertMany 语句:

db.boardGames.insertMany([
{
    "_id" : 1,
    "Game1" : {
        "players" : {
            "Anne" : [97, 165, 101, 67],
            "Pete" : [86, 115, 134, 149],
            "Scott" : [66, 89, 103, 74],
            "Jane" : [113, 144, 125, 99],
            "Katie" : [127, 108, 98, 151]
        }
    },
    "Game2" : {
        "players" : {
            "Margot" : [1, 0, 0, 0],
            "Pete" : [0, 0, 1, 1],
            "Michael" : [0, 0, 0, 0],
            "Jane" : [0, 0, 1, 0]
        }
    },
    "Game3" : {
        "players" : {
            "Chris" : [6, 2, 4, 0, 5, 7],
            "Pete" : [4, 5, 2, 5, 3, 1, 4],
            "Julia" : [3, 7, 4, 0],
            "Tom" : [3, 2, 4, 8, 2, 6, 7]
        }
    }
}]);

【问题讨论】:

  • 模式结构不是很灵活。数据越多,查询就越困难。例如,您如何知道/查询 Chris 在 Game3 中的表现。

标签: arrays mongodb mongodb-query


【解决方案1】:

您拥有的架构并不理想。如果是这样的:https://mongoplayground.net/p/o8m205t9UKG 那么你可以像下面这样查询:

找出每场比赛的获胜者:

db.collection.aggregate(
[
    {
        $set: {
            Players: {
                $map: {
                    input: "$Players",
                    as: "x",
                    in: {
                        Name: "$$x.Name",
                        TotalScore: { $sum: "$$x.Scores" }
                    }
                }
            }
        }
    },
    {
        $unwind: "$Players"
    },
    {
        $sort: { "Players.TotalScore": -1 }
    },
    {
        $group: {
            _id: "$Name",
            Winner: { $first: "$Players.Name" }
        }
    }
])

找到所有游戏中排名前 3 的玩家:

db.collection.aggregate(
[
    {
        $set: {
            Players: {
                $map: {
                    input: "$Players",
                    as: "x",
                    in: {
                        Name: "$$x.Name",
                        TotalScore: { $sum: "$$x.Scores" }
                    }
                }
            }
        }
    },
    {
        $unwind: "$Players"
    },
    {
        $group: {
            _id: "$Players.Name",
            TotalScore: { $sum: "$Players.TotalScore" }
        }
    },
    {
        $sort: { TotalScore: -1 }
    },
    {
        $limit: 3
    },
    {
        $group: {
            _id: null,
            TopRanks: { $push: "$_id" }
        }
    },
    {
        $project: {
            _id: 0,
            TopRanks: 1
        }
    }
])

在所有游戏中找出每一轮的获胜者

db.collection.aggregate(
[
    {
        $set: {
            "Players": {
                $map: {
                    input: "$Players",
                    as: "p",
                    in: {
                        Scores: {
                            $map: {
                                input: "$$p.Scores",
                                as: "s",
                                in: {
                                    Player: "$$p.Name",
                                    Round: { $add: [{ $indexOfArray: ["$$p.Scores", "$$s"] }, 1] },
                                    Score: "$$s"
                                }
                            }
                        }
                    }
                }
            }
        }
    },
    {
        $unwind: "$Players"
    },
    {
        $unwind: "$Players.Scores"
    },
    {
        $replaceRoot: { newRoot: "$Players.Scores" }
    },
    {
        $sort: {
            Round: 1,
            Score: -1
        }
    },
    {
        $group: {
            _id: "$Round",
            Winner: { $first: "$Player" }
        }
    },
    {
        $project: {
            _id: 0,
            Round: "$_id",
            Winner: 1
        }
    },
    {
        $sort: {
            Round: 1
        }
    }
])

【讨论】:

  • 非常感谢!我已经怀疑我的结构并不理想。今晚我会检查你的解决方案并报告。
猜你喜欢
  • 2020-02-06
  • 2021-08-22
  • 1970-01-01
  • 1970-01-01
  • 2021-07-13
  • 1970-01-01
  • 1970-01-01
  • 2017-02-08
  • 2020-04-14
相关资源
最近更新 更多