Выбор каждого N-го элемента из большой коллекции MongoDB с PHP? - PullRequest
9 голосов
/ 12 июня 2011

У меня есть коллекция MongoDB с элементами ~ 4M.

Я хочу получить число Х этих элементов, равномерно распределенных по всей коллекции.

Например, получить 1000 элементов из коллекции- по одной на каждые 4000 строк.

Прямо сейчас я получаю всю коллекцию курсором, а затем пишу только каждый N-й элемент.Это дает мне то, что мне нужно, но первоначальная загрузка огромной коллекции занимает много времени.

Есть ли простой способ сделать это?Прямо сейчас мой угаданный подход состоит в том, чтобы сделать JS-запрос для свойства увеличенного индекса с модулем.Реализация этого в PHP:

db.collection.find({i:{$mod:[10000,0]}})

Но похоже, что для выполнения запроса, вероятно, потребуется столько же времени.

Jer ​​

Ответы [ 6 ]

0 голосов
/ 15 ноября 2014

Простой (неэффективный) способ сделать это с помощью потока.

var stream = collection.find({}).stream();
var counter = 0;

stream.on("data", function (document) {
  counter++;

  if (counter % 10000 == 0) {
    console.log(JSON.stringify(document, null, 2));
    //do something every 10,000th time
  }
});
0 голосов
/ 02 ноября 2011

Разве это не идеальный вариант использования для задания по сокращению карты?

0 голосов
/ 22 сентября 2011

Если бы только ваши данные были в базе данных sql, как и должно быть, ... этот вопрос не был бы в PHP, и ответ был бы таким простым и быстрым ...

Загрузка чего-либо в курсор вместо вычисления информации непосредственно в БД - это определенно плохая идея, разве невозможно сделать это напрямую в MongoDB?

0 голосов
/ 15 июня 2011

Лично я бы разработал значение «модуля», наполнив его чем-то, что является функцией, представляющей данные - так что, если ваши данные вставлялись через регулярные интервалы в течение дня, вы могли бы сделать модуль времени, если естьничего непредсказуемого, тогда вы можете использовать случайное значение;с коллекцией такого размера он будет стремиться к равномерному распределению довольно быстро.

Пример использования случайного значения ...

    // add the index
    db.example.ensureIndex({modulus: 1});
    // insert a load of data
    db.example.insert({ your: 'data', modulus: Math.round((Math.random() * 1000) % 1000) });
    // Get a 1/1000 of the set
    db.example.find({modulus: 1});
    // Get 1/3 of the set
    db.example.find({modulus: { $gt: 0, $lt: 333 }});
0 голосов
/ 15 июня 2011

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

0 голосов
/ 13 июня 2011

Я думаю, что основная проблема заключается в том, что коллекция может быть распределена по серверам, и, следовательно, вам придется выполнять итерацию по всей коллекции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...