Как найти номер строки в отсортированной коллекции MongoDB, чтобы вычислить ее процентиль?

#mongodb

#mongodb

Вопрос:

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

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

 percentile = row_index / total_rows;
  

Как бы это было достигнуто в MongoDB?

Ответ №1:

Получить общее количество с помощью db.yourCollection.count()

Затем подсчитайте записи с большим числом, используя
db.yourCollection.find({$gte: value}).count()

Если общее количество = 1000, считайте больше или равно = 950, тогда у вас получается 950/1000 — top 95%

Но если вы часто используете свою коллекцию в режиме чтения и редко в режиме записи, я бы предложил создать новую временную коллекцию, используя MapReduce, чтобы иметь записи {_id:..., percent:...}

Ответ №2:

Тривиальным решением здесь является сортировка по общему количеству просмотров по убыванию. Затем вы просматриваете результаты курсором, пока не найдете свой идентификатор пользователя.

Очевидно, что это решение не обеспечивает высокой производительности, если вам приходится часто его запускать. Легко получить «топ-20», но гораздо сложнее вычислить «нижние 25%».

Если этот запрос действительно важен или вы часто его выполняете, есть пара обходных путей.

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

 { percent : 95, score : 888888 }
{ precent : 90, score : 777777 }
...
  

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