Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.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 MapReduce使用命令无法从服务器解码文档_Php_Mongodb_Mapreduce_Aggregation Framework - Fatal编程技术网

Php MapReduce使用命令无法从服务器解码文档

Php MapReduce使用命令无法从服务器解码文档,php,mongodb,mapreduce,aggregation-framework,Php,Mongodb,Mapreduce,Aggregation Framework,我有一个Test数据库,其中包含一个名为collection的集合: { "_id": "576008e5b47a6120c800418d", "UserID": "Paul", "Page": "A" } 我想记录webactivity并使用mapreduce获得如下结果 { "_id": "Paul", "value": { "A": 1, "B": 0, "C": 0, "D":

我有一个
Test
数据库,其中包含一个名为
collection
的集合:

 {
    "_id": "576008e5b47a6120c800418d",
    "UserID": "Paul",
    "Page": "A"
 }
我想记录webactivity并使用mapreduce获得如下结果

{
    "_id": "Paul",
    "value": {
        "A": 1,
        "B": 0,
        "C": 0,
        "D": 0,
        "E": 0
    }
}
首先,我尝试了一个PHP 7 MongoDB驱动程序1.1.7 MapReduce的简单代码,使用的命令无法从服务器解码文档:

<?php
$manager = new MongoDB\Driver\Manager("mongodb://localhost:27017");
$command = new MongoDB\Driver\Command(array(
  "mapReduce" => "collection",
  "map" => "function() { emit(this.UserID, 1); }",
  "reduce" => "function(Users, Pages){".
  "return Pages;}",
  "out" => "ex"
));
try {
  $cursor = $manager->executeCommand('Test.collection', $command);
  $response = $cursor->toArray()[0];
} catch(MongoDB\Driver\Exception $e) {
  echo $e->getMessage(), "\n";
  exit;
}
var_dump($response);
?>


任何想法都将不胜感激。

不太确定我是否会推荐MapReduce用于这种类型的操作,我会说聚合框架将以更好的性能进行聚合,因为操作都是在本机代码中完成的,而无需将代码派生到JavaScript进行编译(在MapReduce的情况下)

使用聚合操作,您只需要一个管道,它使用运算符,允许您将逻辑条件转换为值。在这种情况下,您希望将
页面
指定为键,并将其计数指定为值,文档按
用户ID
分组

考虑在mongo shell中运行以下聚合操作:


将产生以下输出:

{
    "_id": "Paul",    
    "A": 1,
    "B": 0,
    "C": 0,
    "D": 0,
    "E": 0    
}
{
    "results" : [ 
        {
            "_id" : "Paul",
            "value" : {
                "A" : 1,
                "B" : 0,
                "C" : 0,
                "D" : 0,
                "E" : 0
            }
        }
    ]
}
对于上面的示例文档


为简洁起见,如果您事先有一个页面列表,则可以按如下方式动态生成管道:

var groupOperation = { "$group": { "_id": "$UserID" } },
    pages = ["A", "B", "C", "D", "E"];

pages.forEach(function (page){
    groupOperation["$group"][page] = {
        "$sum": {
            "$cond": [
                { "$eq": [ "$Page", page ] },
                1,
                0
            ]
        }
    };
})

db.collection.aggregate([groupOperation]);

现在,将其转换为PHP如下:

<?php

$group_pipeline = [
    '$group' => [
        '_id' => '$UserID',
        'A' =>  [ 
            '$sum' =>  [
                '$cond' =>  [ [ '$eq' =>  [ '$Page', 'A' ] ], 1, 0 ]
            ]
        ],
        'B' =>  [ 
            '$sum' =>  [
                '$cond' =>  [ [ '$eq' =>  [ '$Page', 'B' ] ], 1, 0 ]
            ]
        ],
        'C' =>  [ 
            '$sum' =>  [
                '$cond' =>  [ [ '$eq' =>  [ '$Page', 'C' ] ], 1, 0 ]
            ]
        ],
        'D' =>  [ 
            '$sum' =>  [
                '$cond' =>  [ [ '$eq' =>  [ '$Page', 'D' ] ], 1, 0 ]
            ]
        ],
        'E' =>  [ 
            '$sum' =>  [
                '$cond' =>  [ [ '$eq' =>  [ '$Page', 'E' ] ], 1, 0 ]
            ]
        ]
    ],
];
$aggregation = $collection->aggregate([ group_pipeline ]);

?>
它给出了输出:

{
    "_id": "Paul",    
    "A": 1,
    "B": 0,
    "C": 0,
    "D": 0,
    "E": 0    
}
{
    "results" : [ 
        {
            "_id" : "Paul",
            "value" : {
                "A" : 1,
                "B" : 0,
                "C" : 0,
                "D" : 0,
                "E" : 0
            }
        }
    ]
}

将上述mapReduce操作转换为PHP非常简单。

我不太确定我是否会推荐mapReduce用于这种类型的操作,我会说聚合框架将以更好的性能进行聚合,因为操作都是在本机代码中完成的,而无需将代码生成JavaScript进行编译(在MapReduce案例中)

使用聚合操作,您只需要一个管道,该管道使用运算符,允许您将逻辑条件转换为值。在这种情况下,您希望将
页面
指定为键,并将其计数指定为值,文档按
用户ID
分组。

考虑在mongo shell中运行以下聚合操作:


将产生以下输出:

{
    "_id": "Paul",    
    "A": 1,
    "B": 0,
    "C": 0,
    "D": 0,
    "E": 0    
}
{
    "results" : [ 
        {
            "_id" : "Paul",
            "value" : {
                "A" : 1,
                "B" : 0,
                "C" : 0,
                "D" : 0,
                "E" : 0
            }
        }
    ]
}
对于上面的示例文档


为简洁起见,如果您事先有一个页面列表,则可以按如下方式动态生成管道:

var groupOperation = { "$group": { "_id": "$UserID" } },
    pages = ["A", "B", "C", "D", "E"];

pages.forEach(function (page){
    groupOperation["$group"][page] = {
        "$sum": {
            "$cond": [
                { "$eq": [ "$Page", page ] },
                1,
                0
            ]
        }
    };
})

db.collection.aggregate([groupOperation]);

现在,将其转换为PHP如下:

<?php

$group_pipeline = [
    '$group' => [
        '_id' => '$UserID',
        'A' =>  [ 
            '$sum' =>  [
                '$cond' =>  [ [ '$eq' =>  [ '$Page', 'A' ] ], 1, 0 ]
            ]
        ],
        'B' =>  [ 
            '$sum' =>  [
                '$cond' =>  [ [ '$eq' =>  [ '$Page', 'B' ] ], 1, 0 ]
            ]
        ],
        'C' =>  [ 
            '$sum' =>  [
                '$cond' =>  [ [ '$eq' =>  [ '$Page', 'C' ] ], 1, 0 ]
            ]
        ],
        'D' =>  [ 
            '$sum' =>  [
                '$cond' =>  [ [ '$eq' =>  [ '$Page', 'D' ] ], 1, 0 ]
            ]
        ],
        'E' =>  [ 
            '$sum' =>  [
                '$cond' =>  [ [ '$eq' =>  [ '$Page', 'E' ] ], 1, 0 ]
            ]
        ]
    ],
];
$aggregation = $collection->aggregate([ group_pipeline ]);

?>
它给出了输出:

{
    "_id": "Paul",    
    "A": 1,
    "B": 0,
    "C": 0,
    "D": 0,
    "E": 0    
}
{
    "results" : [ 
        {
            "_id" : "Paul",
            "value" : {
                "A" : 1,
                "B" : 0,
                "C" : 0,
                "D" : 0,
                "E" : 0
            }
        }
    ]
}

将上述mapReduce操作转换为PHP非常简单。

结果接缝仅给出访问的所有页面的总数。假设页面已访问,我得到“a”:6,“B”:6,“C”:6,“D”:6,“E”:6。感谢您提供了描述良好的答案。结果接缝仅给出访问的所有页面的总数。假设页面已访问,我得到“a”:6,“B”:6,“C”:6,“D”:6,“E”:6.谢谢你描述得很好的回答。