El mapa de PHP MongoDB reduce la falla de aserción de db

My first go at Map/Reduce using PHP/MongoDB. I am stuck with an error when running the MapReduce command.

Mi código:

$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";
}

When I run the command I'm getting back the error:

assertion wrong type for field (mapreduce) 3 != 2 assertionCode 13111
errmsg db assertion failure
ok 0

I followed pretty closely the example aquí so I'm not sure what is going wrong. Any suggestions appreciated.

preguntado el 31 de julio de 12 a las 15:07

the format of your emit and result in reduce function must be the same. You have re_date in one and last_post in the other. -

1 Respuestas

It is important to remember when using mapReduce() that the return value of the reduce() function needs to be the same shape as the one that you expect to get in the 'values' element of reduce() function -- and that, in turn, needs to be the same shape as what is emitted by the emit() function.

Given a collection containing documents of the following form:

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

The following code will produce the output you want:

<?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" ;
}

?>

Respondido 31 Jul 12, 23:07

Thank you very much, this is exactly what I needed. Your code to get the max date is much better than what I had also. - johnmcp

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.