我有这样的代码:
// construct map and reduce functions
$map = new MongoCode("
function() { ".
"var key = {date: this.timestamp.getFullYear()+this.timestamp.getMonth()+this.timestamp.getDate()};".
"emit(key, {count: 1});
}"
);
$reduce = new MongoCode("
function(k, vals) { ".
"var sum = 0;".
"for (var i in vals) {".
"sum += vals[i];".
"}".
"return sum;".
"}"
);
$dates = $db->command(array(
"mapreduce" => "items",
"map" => $map,
"reduce" => $reduce,
//"query" => array("type" => "sale"),
"out" => array("merge" => "distinct_dates")
)
);
但是当测试时得到这个错误:
Array ([assertion] => map invoke failed: JS Error: TypeError: this.timestamp.getFullYear is not a function) nofile_b:0 [assertionCode] => 9014 [errmsg] => db assertion failure [ok] => 0) Cron run finished.
集合中的每个对象都有一个时间戳,我想从中提取一个日期(Ymd),并将每个不同的日期放在一个新的集合中。
在MongoDB中,您不能按原样存储Date对象。你的时间戳是int类型的。我希望,如果你这样定义你的map函数,一切都会好起来的:
$map = new MongoCode("
function(){
var date = new Date(this.timestamp * 1000) //JS Date need milliseconds
var key = date.getFullYear() + date.getMonth() + date.getDate();
emit(key, {count: 1})
}
")
问题在于您的"timestamp"字段的类型不正确。如果您将其存储为纯字符串,如:
"timestamp" : "Wed May 05 2010 15:37:58 GMT-0400 (EDT)"
你会得到这个错误。将其更改为以下内容将使您的映射按预期工作:
new Date("Wed May 05 2010 15:37:58 GMT-0400 (EDT)")
当你看到它作为ISODate()
对象存储在Mongo的输出中时,你就知道你在正确的轨道上了。