2012-07-31 41 views
2

我首先在Map/Reduce中使用PHP/MongoDB。運行MapReduce命令時出現錯誤。PHP MongoDB映射reduce db斷言失敗

我的代碼:

$map = "function() {".                            
"emit(this.topic_id, {re_date:this.date_posted}); " .                  
"}"; 

$reduce = "function (key, values) {" . 
"var result = {last_post: 0};" .                         
"var max = ISODate('1970-01-01T00:00:00Z');" .                    
"values.forEach(function (value) {" . 
     "if (max == ISODate('1970-01-01T00:00:00Z')) {" . 
      "max = value.re_date;}" . 
     "if (max < value.re_date) {max = value.re_date;}});" .  
"result.last_post = max;" .                     
"return result;" .                        
"}"; 



$mapFunc = new MongoCode($map); 
$reduceFunc = new MongoCode($reduce); 

$collection = new MongoCollection($db, 'posts'); 
$command = array(
'mapreduce' => $collection, 
'map' => $mapFunc, 
'reduce' => $reduceFunc, 
"query" => array("topic_id" => "2116"), 
"out" => array("merge" => "eventCounts")); 


$threadInfo = $db->command($command); 

$threadsCollection = $db->selectCollection($threadInfo['result']); 

$stats = $statsCollection->find(); 

foreach ($stats as $stat) { 
    echo $stats['_id'] .' Visited '; 
    foreach ($stats['value']['types'] as $type => $times) { 
     echo "Type $type $times Times, "; 
    } 
    foreach ($stats['value']['tags'] as $tag => $times) { 
     echo "Tag $tag $times Times, "; 
    } 
    echo "\n"; 
} 

當我跑我找回了錯誤的命令:

斷言錯誤類型字段(MapReduce的)3 = 2 assertionCode 13111
ERRMSG分貝!斷言失敗
好的0

我跟着非常密切的例子here所以我不知道什麼是goi恩錯了。 任何建議表示讚賞。

+3

您EMIT的格式,導致減少功能必須是相同。你有一個re_date在另一個last_post。 – 2012-07-31 16:50:35

+0

就是這樣,謝謝 – johnmcp 2012-07-31 21:07:55

回答

3

使用mapReduce()時,請記住reduce()函數的返回值需要與您期望在reduce()函數的'values'元素中獲得的形狀相同的形狀,這一點很重要 - - 而這又需要與emit()函數發出的形狀相同。

給出一個包含有下列形式的文檔的集合:

> db.posts.count(); 
1000 
> db.posts.findOne(); 
{ 
    "_id" : 0, 
    "date_posted" : ISODate("2012-04-04T05:54:44.535Z"), 
    "topic_id" : "sierra" 
} 

下面的代碼會產生你想要的輸出:

<?php 

$conn = new Mongo("localhost:$port"); 
$db = $conn->test; 
$collection = $db->tst; 

$map = new MongoCode(
    "function() { emit(this.topic_id, { last_post: this.date_posted }); }" 
); 

$reduce = new MongoCode(
    "function(key, values) { ". 
     "var max = ISODate('1970-01-01T00:00:00Z'); ". 

     "values.forEach(function(val) { ". 
      "if (max < val.last_post) max = val.last_post; ". 
     "}); ". 

     "return {last_post : max}; " . 
    "}" 
); 


$result = $db->command(array(
    "mapreduce" => "posts", 
    "map" => $map, 
    "reduce" => $reduce, 
    "query" => array("topic_id" => "alpha"), 
    "out" => array("merge" => "lastPosts") 
    ) 
); 
echo "result: "; print_r($result); 

$collection = $db->lastPosts; 
$cursor = $collection->find()->limit(6); 

date_default_timezone_set("UTC"); 
foreach($cursor as $doc) { 
    $date = date("r", $doc['value']['last_post']->sec); 
    echo $doc['_id'] . " last visited at " . $date ."\n" ; 
} 

?> 
+0

非常感謝,這正是我所需要的。你獲得最大日期的代碼比我所擁有的要好得多。 – johnmcp 2012-08-01 15:30:21