2013-03-03 2 views
3

У меня есть база данных, где я храню много данных и генерирую виды для графиков. Вместо того, чтобы возвращать все данные для графика, я возвращаю только предопределенное количество выборок. То, как я в настоящее время это делаю, это использовать работу с картой/сокращением на манго, но я не знаю, эффективен ли способ, которым я это делаю, занимает 14 секунд и привязывает процессор на графике, который содержит более 89000 образцов для пример.Эффективная выборка в mongodb

Работа с нисходящей выборкой выполняется путем вычисления «разрешения», то есть (всего # точек)/(желаемое количество выборок). Затем он сохраняет и внешний счет и индекс с использованием переменных области. Затем он в основном смотрит на каждую точку и решает, включать ли ее в список результатов на основе разрешения и текущего состояния переменных count/index.

Это прекрасно работает, но довольно медленно и, вероятно, не масштабируется. Мне интересно, было бы лучше, например, просто вернуть все точки и выполнить выборку в рубине, или, может быть, есть еще лучший способ.

+1

Ознакомьтесь с новой структурой агрегации для Mongo. http://docs.mongodb.org/manual/applications/aggregation/ Вы можете делать агрегации (очевидно), и это намного, намного быстрее, чем map/reduce. – ryan1234

+0

Спасибо, я не уверен, что могу в скором времени собрать агрегаты. Сейчас я понижаю дискретизацию на основе смещения документа в массиве после сортировки. Я думаю, что это лучший способ сделать это, хотя бы по значению x в документе. Например, у меня есть данные от x = 10000 до x = 100 000 000 с 100 000 точек данных. Я хочу уменьшить это до 1000 пунктов, равномерно распределенных по всему домену х (10 000 - 1 000 000). Какой был бы лучший способ сделать это? –

+0

Итак, у вас есть 100k элементов в массиве в документе? – ryan1234

ответ

3

В случае, если кто-то заинтересован, это решение, с которым я столкнулся. Мне потребовалось некоторое время, чтобы понять из-за некоторых ограничений mongodb, но он работает очень хорошо и в 10 раз быстрее, чем мое текущее решение для уменьшения карты.

Вот код агрегации:

db.data.aggregate(
    {$match: {$and: [{graph_id: gid}, {"x.value": {$gt: start, $lt: stop}}]}}, 
    {$project: {x: 1, y: 1, series: 1, chunk: {$subtract: [{$divide: ["$x.value", step]}, {$mod: [{$divide: ["$x.value", step]}, 1]}]}}}, 
    {$group: { 
    _id: { 
     chunk: "$chunk", 
     series: "$series" 
    }, 
    series: {$first: "$series"}, 
    x: {$first: "$x"}, 
    y: {$first: "$y"}, 
    } 
    }, 
    {$sort: {"x.value": 1}} 
) 

Это решение Куски данные. Я хотел сделать что-то вроде int (x.value/step), но mongodb не имеет целочисленных математических операторов. Поэтому мне пришлось подделать его ((x.value/step) - ((x.value/step)% 1)), который дает вам целую часть деления.

Это хорошо работает и позволит вам делать что-то вроде средних кусков, а не просто выбирать первый, довольно легко.

Смежные вопросы