我尝试在我的 php 应用程序中使用以下 mongo shell 代码。 它基本上是在一个时间范围内获取 800 个均匀分布的值,用于图表中。
var map = function () {
if (endTime < 0) {
var start = new ISODate("2013-09-01T00:00:00.000Z");
var end = new ISODate("2013-11-01T00:00:00.000Z");
var startMilli = start.getTime();
var endMilli = end.getTime();
var interval = endMilli - startMilli;
delta = interval / 800;
endTime = startMilli + delta;
}
if (endTime < this.date.getTime()) {
resArray = {};
while (endTime < this.date.getTime()) {
endTime += delta;
}
}
var id = this.homeId + this.sensor;
if (typeof resArray[id] == 'undefined') {
resArray[id] = 1;
emit({
homeId: this.homeId,
sensor: this.sensor,
date: this.date,
val: this.val
}, {
x: 1
});
}
};
var reduce = function (key, values) {
return values[0];
};
db.passiv.mapReduce(
map,
reduce,
{ query:
{ homeId: 35600,
sensor : {
$in :[ "z1t","ts1"]
},
date : {
$gte : new ISODate("2013-09-01T00:00:00.000Z"),
$lte : new ISODate("2013-11-01T00:00:00.000Z")
} },
scope : {
resArray : {},
delta : -1,
endTime : -1
},
out: 'TEST1',
sort : {
date:1
}
});
它在 shell 中执行良好,但我尝试将其转换为 php 没有给我任何结果:
$from = '2013-09-01T00:00:00.000Z';
$to = '2013-11-01T00:00:00.000Z';
$map = new MongoCode("
var map = function () {
if (endTime < 0) {
var start = new ISODate(".$from.");
var end = new ISODate(".$to.");
var startMilli = start.getTime();
var endMilli = end.getTime();
var interval = endMilli - startMilli;
delta = interval / 800;
endTime = startMilli + delta;
}
if (endTime < this.date.getTime()) {
resArray = {};
while (endTime < this.date.getTime()) {
endTime += delta;
}
}
var id = this.homeId + this.sensor;
if (typeof resArray[id] == 'undefined') {
resArray[id] = 1;
emit({
homeId: this.homeId,
sensor: this.sensor,
date: this.date,
val: this.val},
{ x: 1 });
}
};");
$reduce = new MongoCode('
var reduce = function (key, values) {
return values[0];
};');
$constraint = array('homeId' => 32168);
$date = array('$gte' => new MongoDate(1377986400), '$lt' => new MongoDate(1383260400));
$condition = array_merge($constraint, $date, array("sensor" => array('$in' => array('z1t', 'ts1'))));
$rs = $passivCollection->command(
array(
"mapreduce" => "passiv",
"query" => $condition,
"map" => $map,
"reduce" => $reduce,
"scope" => array(
"resArray" => array(),
"delta" => -1,
"endTime" => -1
),
"out" => "TEST1",
"sort" => array("date" => 1)
));
不知何故,我认为最后命令中的范围无法正常工作,而且我似乎无法在任何地方找到范围方面的任何有用信息。非常感谢任何帮助。
在 PHP 中执行 MapReduce 的一个很好的示例位于此处:http://php.net/manual/en/mongodb.command.php 示例 #3。
基本上,您遇到的问题之一是
MongoCode
对象不再代表匿名函数,而是代表无法返回的变量。
相反,您想要定义您的函数,例如:
$reduce = new MongoCode('
function (key, values) {
return values[0];
};
');
我认为这应该可以解决问题。
您的编辑中的 PHP 有问题:
$start = new MongoDate(strtotime("2013-09-01 00:00:00"));
$end = new MongoDate(strtotime("2013-11-01 00:00:00"));
$constraint = array('homeId' => '32168');
$date = array('$gte' => $start, '$lt' => $end);
$sensors = array('z1t');
$condition = array_merge($constraint, $date, array("sensor" => array('$in' => $sensors)));
var_dump($condition);
$tt = $passivCollection->selectCollection('passiv')->count($date);
var_dump($tt);
您正在使用:
$date = array('$gte' => $start, '$lt' => $end);
无需定义应搜索的字段。尝试:
$start = new MongoDate(strtotime("2013-09-01 00:00:00"));
$end = new MongoDate(strtotime("2013-11-01 00:00:00"));
$constraint = array('homeId' => '32168');
$date = array('date' => array('$gte' => $start, '$lt' => $end));
$sensors = array('z1t');
$condition = array_merge($constraint, $date, array("sensor" => array('$in' => $sensors)));
var_dump($condition);
$tt = $passivCollection->selectCollection('passiv')->count($date);
var_dump($tt);
其中
date
字符串位于:
$date = array('date' => array('$gte' => $start, '$lt' => $end));
替换为您的字段名称。