2011-04-26 3 views
4

J'ai une grande collection MongoDB qui contient un userID et un compteur représentant le nombre total de visites pour cet utilisateur au fil du temps. J'aimerais pouvoir calculer un percentile d'utilisateurs donné.Comment trouver le numéro de ligne d'une rangée dans une collection MongoDB triée pour calculer son centile?

Conceptuellement, ce que je voudrais faire est une sorte de collecte, puis obtenir le numéro de ligne pour l'enregistrement de cet utilisateur donné et diviser ce nombre par le nombre total de la collection:

percentile = row_index/total_rows; 

Comment cela être accompli dans MongoDB?

Répondre

2

La solution triviale ici est de trier par nombre total de résultats décroissants. Vous passez ensuite à travers les résultats jusqu'à ce que vous trouviez votre UserID.

De toute évidence, cette solution n'offre pas de grandes performances si vous devez l'exécuter beaucoup. Il est facile d'obtenir un «top 20», mais c'est beaucoup plus de calculer un «bottom 25%».

Si cette requête est vraiment importante ou si vous l'utilisez beaucoup, il existe plusieurs solutions de contournement.

Je pense que le plus simple est simplement d'exécuter un travail qui construit les centiles pour vous sur une base régulière. Fondamentalement, vous construisez une collection qui ressemble à ceci:

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

Pour obtenir le percentile d'un utilisateur, vous regardez leur score dans cette collection relativement faible. Pour mettre à jour ces scores, exécutez simplement un travail sur une base régulière qui traverse l'ensemble de l'utilisateur.

4

Obtenir nombre total par db.yourCollection.count()

compter ensuite record qui ont plus grand nombre en utilisant
db.yourCollection.find({$gte: value}).count()

Si nombre total = 1000, comptent pour plus ou égal = 950 alors que vous avez dans 950/1000 - top 95%

Mais si vous utilisez votre collection souvent en mode lecture et rare en mode d'écriture, je vous suggère de faire une nouvelle collection temporaire en utilisant MapReduce pour avoir des enregistrements {_id:..., percent:...}

Questions connexes