2014-11-27 3 views
0

Мне нужно рассчитать ранги процентиля определенного значения против большого количества значений, отфильтрованных различными способами. Все данные хранятся на Parse.com, который имеет ограничение на возврат не более 1000 строк на запрос. Количество сохраненных значений, вероятно, превысит 100 000.Вычислить ранжирование процентиля (парсе)

Под «процентильным рангом», я имею в виду, мне нужно рассчитать процент значений, которые предоставленное значение больше. Я не пытаясь вычислить значение предоставленного процентиля. Например, с учетом списка значений {20, 23, 24, 29, 30, 31, 35, 40, 40, 43} ранжирование процентиля предоставленного значения 35 составляет 70%. Алгоритм для этого - просто ранг значения/подсчета значений * 100. Не уверен, что для этого является правильной терминологией.

Я рассмотрел несколько разных подходов к этому. Первый заключается в том, чтобы вытащить полный список значений (в Parse Cloud), а затем вычислить ранг процентиля, затем отфильтровать список и рассчитать снова, повторяя последние два шага столько раз, сколько требуется. Проблема с этим подходом заключается в том, что он не будет работать, если мы достигнем 1000 значений, чего можно ожидать довольно быстро.

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

var rank_world_alltime = new Parse.Query("Values") 
    .lessThan("value", request.params.value) // Filters query to values less than the provided value, so counting this query will return the rank 
    .count(); 

var count_world_alltime = new Parse.Query("Values") 
    .count(); 

Parse.Promise.when(rank_world_alltime, count_world_alltime).then(function(rank, count) { 
    percentile = rank/count * 100; 
    console.log("world_alltime_percentile = " + percentile); 
}); 

Это хорошо работает для одного вычисления, но мне нужно выполнить несколько вычислений, и этот подход очень быстро становится много запросов. Я ожидаю, что вам нужно будет выполнить около 15 вычислений за звонок, что составляет 30 запросов. Все вычисления должны завершиться менее чем за 3 секунды до того, как Parse прекратит работу, и я ограничусь 30 reqs/second, так что это очень быстро станет проблемой.

Есть ли у кого-нибудь какие-либо предложения о том, как еще я мог бы подойти к этому? Я подумал о том, чтобы каким-то образом предварительно обработать некоторые из них, но не могу понять, как это сделать, поскольку фильтры будут основываться на времени и местоположении (городе и стране), поэтому существует потенциально много предварительных вычислений которые должны выполняться через равные промежутки времени. Результаты не должны быть на 100% точными, но что-то близко.

ответ

0

Я мало разбираюсь в синтаксическом анализе, но насколько я понимаю, что вы говорите, это какая-то облачная база данных, которая держит ваши символы, и ограничивает вас 1000 строк на запрос, 3 секунды на задание и 30 запросов в секунду.

Для того чтобы иметь приблизительные вычисления и разделить на 2 количество запросов, я бы в первую очередь кэшировал общее количество (count_world_alltime, count_region, week, whatever). Если вы можете сохранить их где-то локально. Для чисел 100K, просто получающих порядок (при этом не последний обновленный номер) должно быть достаточно хорошим, чтобы получить процентиль.

Возможно, вы сможете получить несколько счетов за запрос. Однако мой недостаток опыта в parse/nosql не позволяет мне быть уверенным в этом, вам придется проверить их документацию.Если это возможно, однако, в случае, когда вам нужно процентили для серии значений всех в одной и той же категории, я бы

  • Заказ значения, давайте называть их, б, в, д, е (один раз)
  • Получить количество значений между интервалами [0, a] [a, b] [b, c] [c, d] [d, e]
  • Используйте кэшированную сумму, чтобы получить процентили (где NXY это количество значений в [х, у]):
    • Па = 100 * N0a/общее
    • Pb = 100 * (N0a + NAB)/общее
    • Pc = 100 * (N0a + Наб + Nbc)/общее
    • и так далее ...

Если вам нужно значение занимает во всем мире, а другой в регионе, некоторые в неделю другие в течение всех времен и т. д. это не применяется. В этом случае я не думаю, что вы можете получить ниже 1 запроса/числа с кешированием итогов.

+0

Спасибо за ваш ввод @Cimblali. Это интересный подход, который был бы полезен в несколько ином сценарии. Это не совсем соответствует моим требованиям (мне нужны ценности, оцененные по всему миру, по стране/городу, за определенный промежуток времени, а также комбинация каждого из них - город на прошлой неделе, страна за последнюю неделю и т. Д.), Но может быть способный использовать подобный подход. Я думаю, что мой лучший выбор может состоять в том, чтобы перейти на базу данных на основе SQL. – JoGoFo

+0

@JoGoFo Ну, слишком плохо. Надеемся, вы все равно можете кэшировать общие числа. Хотя эти запросы могут выполняться довольно быстро, если у вас есть индексы или что-то в этом роде, это все равно поможет вам с ограничением на общее количество запросов. – Cimbali

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