简体   繁体   English

在 MongoDB 中对嵌套数组列表中的匹配元素进行排序和排序

[英]Sorting and ranking matching elements in a nested array list in MongoDB

Greetings fellow fans of MongoDB!问候 MongoDB 的粉丝!

I've got here a data structure with board game data where achieved scores (after every round) are tracked as nested arrays associated with the player's name.我在这里有一个包含棋盘游戏数据的数据结构,其中所获得的分数(每轮之后)被跟踪为与玩家姓名相关的嵌套 arrays。 Note that with each board game there's a different set of players:请注意,每个棋盘游戏都有一组不同的玩家:

{
"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]
        }
    },
}
  • Game1: Players earn as many victory points per round as they can游戏1:玩家每轮尽可能多地获得胜利点数
  • Game2: Winning around earns 1, losing a round 0游戏2:赢一局赚1,输一局0
  • Game3: Players may leave after every round, hence some players have played more rounds than others, so these arrays are different in their length Game3:玩家可能在每回合结束后离开,因此有些玩家的回合数比其他玩家多,因此这些 arrays 的长度不同

So, here are my questions:所以,这是我的问题:

  1. Which player got the most points in each game?哪位球员在每场比赛中得分最高? Who the least?谁最少?
  2. Who is the winner in the first round?谁是第一轮的获胜者? 2nd round, etc.第二轮等
  3. Who is sitting on 1st, 2nd and 3rd rank from all played games?谁坐在所有玩过的游戏中排名第一、第二和第三?

I've done quite some queries with mongo, but so far with a nested array that is attached to a flexible/unpredictable parent node I have no idea how to write a query.我已经用 mongo 完成了一些查询,但到目前为止,使用一个嵌套数组附加到一个灵活/不可预测的父节点,我不知道如何编写查询。 Also, maybe this is not the best way how I structured the data.此外,也许这不是我构建数据的最佳方式。 So in case you have a better idea, I'd be happy to learn!所以如果你有更好的主意,我很乐意学习!

Cheers!干杯!

PS: The insertMany statement to above JSON data: PS:上面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]
        }
    }
}]);

the schema you have is not ideal.您拥有的架构并不理想。 if it was something like this: https://mongoplayground.net/p/o8m205t9UKG then you can query like the following:如果是这样的: https://mongoplayground.net/p/o8m205t9UKG那么你可以像下面这样查询:

find winner of each game:找到每场比赛的获胜者:

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" }
        }
    }
])

find top 3 ranking players across all games:查找所有游戏中排名前 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
        }
    }
])

find the winner of each round across all games在所有游戏中找到每一轮的获胜者

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
        }
    }
])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM