Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP MongoDB按键选择字段(不同)_Php_Mongodb_Aggregation Framework - Fatal编程技术网

PHP MongoDB按键选择字段(不同)

PHP MongoDB按键选择字段(不同),php,mongodb,aggregation-framework,Php,Mongodb,Aggregation Framework,我有一个世界各地彩票游戏的数据库。 以下是每个文档的外观: 如果国家有州(加拿大、美国),每个游戏都可以使用不同的国家代码或州代码 选择所有游戏id,然后选择它所属的所有国家和/或州,如下所示: // get all games // $colCurrent = MongoCollection Object $gamesRes = $colCurrent->distinct('game_id'); foreach($gamesRes as $gameId) { $disCount

我有一个世界各地彩票游戏的数据库。 以下是每个文档的外观:

如果国家有州(加拿大、美国),每个游戏都可以使用不同的国家代码或州代码

选择所有游戏id,然后选择它所属的所有国家和/或州,如下所示:

// get all games
// $colCurrent = MongoCollection Object
$gamesRes = $colCurrent->distinct('game_id');
foreach($gamesRes as $gameId) {
    $disCountries = $colCurrent->distinct('country_code',array('game_id' => $gameId));
    $disStates = $colCurrent->distinct('state_code',array('game_id' => $gameId));
}
我认为这样做是不合适的,因为它会对数据库进行大量查询。 我尝试过使用聚合函数,但它只选择了1个字段,比如distinct

有人可以帮助优化此查询吗


非常感谢

根据您要实现的目标和数据集的大小,您可以采取几种不同的方法

mongo
shell(MongoDB 2.2+)中使用的一些示例:

1) 查找所有游戏,并为每个游戏创建一组唯一的国家代码和州代码值:

db.games.aggregate(
    { $group: {
        _id: { gameId: "$game_id" },
        countries: { $addToSet: "$country_code" },
        states: { $addToSet: "$state_code" }
    }}
)
2) 查找所有游戏,并按gameId、国家代码和州代码的唯一组合分组,包括计数:

db.games.aggregate(
    { $group: {
        _id: {
            gameId: "$game_id",
            country_code: "$country_code",
            state_code: "$state_code"
        },
        total: { $sum: 1 }
    }}
)
在第二个示例中,请注意用于分组的
\u id
可以包括多个字段


如果不想对集合中的所有文档进行分组,可以从开始将管道限制为所需的数据,从而提高这些聚合的效率(
$match
还可以利用适当的索引).

假设您指的是每个游戏名称的不同国家的总数和不同国家的总数(假设每个游戏id有一个,并且更易于阅读[必要时交换])

发布为mongo shell,以便更清晰,根据需要调整您的驱动程序和语言:

db.lottery.aggregate([
    {$project: { country_code: 1, state_code: 1, game_name: 1 } },
    {$group: { 
        _id: "$game_name",
        countries: {$addToSet: "$country_code"},
        states: {$addToSet: "$state_code"}
    }},
    {$unwind: "$countries"},
    {$group:{ _id: { id: "$_id", states: "$states" }, country_count: {$sum: 1 } }},
    {$project: { _id: 0, game: "$_id.id", countries: "$country_count", states: "$_id.states" }},
    {$unwind: "$states"},
    {$group: { _id: { id: "$game", countries: "$countries" }, state_count: {$sum: 1 } }},
    {$project: { _id: 0, game: "$_id.id", countries: "$_id.countries", states: "$state_count" }},
    {$sort: { game: 1 }}
])
所以这里有几个奇特的阶段:

  • 投影仅需要的字段
  • 在游戏中分组,将每个国家和州推到自己的阵列中
  • 现在,解开这些国家,每个国家获得一项记录
  • 在保留游戏和状态场阵列的同时,将国家和分组
  • 项目--可选--使记录看起来更自然$组与_id发生冲突
  • 展开状态以获得每个状态的一条记录
  • 将a组的州数相加,同时保留游戏和国家数
  • 投射到更自然的事物中
  • 排序——可选——按您喜欢的排序。在这种情况下,游戏的名称
  • 呸!这是一个相当大的总数,但它确实显示了解决问题的方法

    免责声明:

    我在这里做了一个巨大的假设,即你的数据已经有了一定的意义,每个国家和/或每个州没有多个比赛记录。另外一个“我没有做过”的部分是,你的代码没有识别出国家内部的状态,所以“我也没有做过”:-P

    不过,您可以添加$group阶段来完成此操作。编程的一部分乐趣是学习和解决如何自己做事情。所以这应该是一个很好的开始,如果不是一个完美的适合


    对于学习如何应用此处使用的所有运算符来说,是一个非常好的地方。一次应用一个阶段(数据大小允许)以了解每个步骤中的情况。

    您想要得到的最终结果是什么?例如:所有游戏的列表,以及每个游戏出现的国家和州?是!比如:游戏id:801在国家:美国在州:NY AZ FL等等。我可能对这个问题有很大的误解,做了很多不需要的额外工作。希望对某人有用。非常感谢你的辛勤工作:)我会看看的。如果它不适合我的问题,它仍然有一个很好的输入和关于mongo聚合的知识!我想$addToSet就是我要找的。让我检查一下,我会回来接受答案或继续解释。谢谢你的回答!