Подтвердить что ты не робот

MongoDB MapReduce не возвращает данные в PHP

Я использую 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, которое я делаю выше? Есть ли другие шаги, которые я могу предпринять, чтобы попытаться отладить это?

Пожалуйста, дайте мне знать, будет ли полезно предоставлять дополнительную информацию. Я ценю, что это несколько экспансивный и непонятный вопрос, но я постарался изо всех сил сообщить об этом! Надеюсь, кто-то может предложить выход из этого.

Большое спасибо за чтение!

4b9b3361

Ответ 1

Для будущих читателей эта проблема оказалась результатом несовместимой обработки целых/числовых строк в другом месте приложения. Извините за красную селедку!