Я использую MapReduce монго для выполнения операции для подсчета количества слов на наборе документов. Документы очень просты (просто идентификатор и хеш слов):
{ "_id" : 6714078, "words" : { "my" : 1, "cat" : 1, "john" : 1, "likes" : 1, "cakes" : 1 } }
{ "_id" : 6715298, "words" : { "jeremy" : 1, "kicked" : 1, "the" : 1, "ball" : 1 } }
{ "_id" : 6717695, "words" : { "dogs" : 1, "can't" : 1, "look" : 1, "up" : 1 } }
Базу данных называют "словами" в моей среде, рассматриваемые наборы называют "wordsX", где X число категории (я знаю, не спрашивайте). Поле в хеше документа, где слова хранятся, также называют "словами". Gah.
Проблема, которую я имею, что происходит в определенных условиях в моем приложении PHP, MapReduce не возвращает данных. Раздражающе, выполнение тех же команд от оболочки монго дает идеальные результаты. Я пытаюсь придавить, где эта ошибка происходит, но я действительно озадачен, так надеясь, что кто-то смог проливать некоторый свет на это. Подход к этому вопросу действительно продолжается немного, потому что среда является немного сложной, но терпите меня.
Команды, которые я попытался выполнить от оболочки монго для тиражирования основанных на PHP операций, следующие:
m = function () {
if (this.words) {
for (index in this.words) {
emit(index, this.words[index]);
}
}
}
r = function (key, values) {
var total = 0;
for (var i in values) {
total += values[i];
}
return total;
}
res = db.words.mapReduce(m, r, { query : { _id : { $in : [6714078,6715298,6717695] } } });
Это приводит к временному набору, создаваемому содержащий данные для подсчета количества слов. Весь OK до сих пор.
Однако, если я выполняю те же команды от PHP (пользующийся стандартной библиотекой монго), я заканчиваю без данных при определенных условиях. Это немного хитро для описания, потому что я не хочу к скуке Вас с деталями приложения/среды вне монго, но в основном я использую Сфинкса для фильтрации некоторых записей, затем предоставляя список идентификаторов содержания к монго, на котором выполняется MapReduce. Если я проникаю назад в набор данных на 2 или 3 дня, я возвращаю результаты от монго; если я не фильтрую, я возвращаю пустой набор данных. Код PHP для выполнения той же операции следующие. Я не включал Основанные на сфинксе части, поскольку я не думаю, что они релевантны (просто знают, что мы возвращаем список идентификаторов), потому что я попытался предоставить точно тот же список к монго на командной строке и получил правильные результаты, тогда как я не делаю из PHP. Надежда, которая имеет смысл.
Код PHP, который я использую, похож на это:
$objMongo = new Mongo();
$objDB = $objMongo->words;
$arrWordList = array();
$strMap = '
function() {
if (this.words) {
for (index in this.words) {
emit(index, this.words[index]);
}
}
}
';
$strReduce = '
function(key, values) {
var total = 0;
for (var i in values) {
total += values[i];
}
return total;
}
';
$objMapFunc = new MongoCode($strMap);
$objReduceFunc = new MongoCode($strReduce);
$arrQuery = array(
'_id' => array('$in' => $arrIDs) // <--- list of IDs from Sphinx
);
$arrCommand = array(
'mapreduce' => 'wordsX',
'map' => $objMapFunc,
'reduce' => $objReduceFunc,
'query' => $arrQuery
);
MongoCursor::$timeout = -1;
$arrStatsInfo = $objDB->command($arrCommand);
var_dump($arrStatsInfo);
Содержание массива информации результата ($arrStatsInfo
) при работе и нерабочих условиях (фильтрация, как указано выше) следующие.
Рабочие результаты:
array(4) {
["result"]=>
string(31) "tmp.mr.mapreduce_1279637336_227"
["timeMillis"]=>
int(171)
["counts"]=>
array(3) {
["input"]=>
int(54)
["emit"]=>
int(2517)
["output"]=>
int(1526)
}
["ok"]=>
float(1)
}
Пустые результаты:
array(4) {
["result"]=>
string(31) "tmp.mr.mapreduce_1279637381_228"
["timeMillis"]=>
int(21)
["counts"]=>
array(3) {
["input"]=>
int(0)
["emit"]=>
int(0)
["output"]=>
int(0)
}
["ok"]=>
float(1)
}
Таким образом, это похоже при нарушенном условии, никакие записи даже не превращают его в MapReduce. Я потратил возрасты, пытающиеся разрабатывать то что же, спрашивается, продолжается здесь, но у меня не было понимания к настоящему времени. Как я сказал, выполнение тех же команд (как выше) непосредственно в командной строке монго, использующей точно тот же набор идентификаторов, возвращает правильные результаты.
В конце концов, это, я предполагаю, что мой вопрос: есть ли что-нибудь, очевидно, неправильно со взаимодействием PHP-монго, которое я делаю выше? Есть ли другие шаги, которые я могу сделать, чтобы попытаться отладить это?
Сообщите мне, если предоставление дальнейшей информации было бы полезно. Я ценю, это - несколько расширяемый и неточный вопрос, но я старался изо всех сил передавать проблему! Действительно надежда кто-то может предложить выход из этого.
Большое спасибо за чтение!