Я использую Mongo 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 } }
База данных называется "словами" в моей среде, соответствующие коллекции называются "словаX", где X - номер категории (я знаю, не спрашиваю). Поле в хеше документа, где хранятся слова, также называется "слова". Г.
Проблема, с которой я сталкиваюсь, заключается в том, что при определенных условиях в моем приложении PHP MapReduce не возвращает никаких данных. Раздражающе, выполнение тех же команд из оболочки Mongo дает отличные результаты. Я пытаюсь определить, где эта ошибка, но я действительно тупой, поэтому надеюсь, что кто-то сможет пролить свет на это. Представление этого вопроса действительно идет немного, потому что среда немного сложна, но, пожалуйста, несите меня.
Команды, которые я пытался запустить из оболочки Mongo для репликации операций на основе 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] } } });
В результате создается временная коллекция, содержащая данные о количестве слов. Все ОК до сих пор.
Однако, если я запускаю те же команды из PHP (используя стандартную библиотеку Mongo), я не получаю никаких данных при определенных условиях. Это немного сложно описать, потому что я не хочу рассказывать вам о деталях приложения/среды за пределами Mongo, но в основном я использую Sphinx для фильтрации некоторых записей, а затем поставляю список идентификаторов контента Mongo, на которых Выполняется MapReduce. Если я отфильтрую обратно в набор данных на 2 или 3 дня, я получаю результаты от Mongo; если я не фильтрую, я получаю пустой набор данных. Код PHP для запуска той же операции выглядит следующим образом. Я не включил части на основе Sphinx, поскольку я не думаю, что они релевантные (просто знаю, что мы получаем список идентификаторов назад), потому что я попытался предоставить точно такой же список Mongo в командной строке и получил правильные результаты, тогда как я не из 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);
Содержимое массива result-info ($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. Я провел годы, пытаясь понять, что происходит здесь, но до сих пор я не знал. Как я уже сказал, запуск тех же команд (как указано выше) непосредственно в командной строке Mongo с использованием точно такого же набора идентификаторов возвращает правильные результаты.
После всего этого, я думаю, мой вопрос: есть ли что-то явно неправильное с взаимодействием PHP-Mongo, которое я делаю выше? Есть ли другие шаги, которые я могу предпринять, чтобы попытаться отладить это?
Пожалуйста, дайте мне знать, будет ли полезно предоставлять дополнительную информацию. Я ценю, что это несколько экспансивный и непонятный вопрос, но я постарался изо всех сил сообщить об этом! Надеюсь, кто-то может предложить выход из этого.
Большое спасибо за чтение!