Dynamic rating MongoDB

I use MongoDB and have a collection with about 100,000 entries.

Records contain the following data:

{"page": "page1", "user_count": 1400} {"page": "page2", "user_count": 1100} {"page": "page3", "user_count": 900} ... 

I want to infer the ranking of entries according to user_count, for example:

 #1 - page1 #2 - page2 #3 - page3 ... 

... so far so good. I can just use a loop counter if I just output a sorted list. :)

But I also have to support various search queries. So, for example, I get 20 results and want to show on what ranking the results are. How:

 #432 - page1232 #32 - page223 #345 - page332 ... 

What is the best way to do this? I do not want to keep the rating in the collection, as the collection is constantly changing. I tried to solve it using the search dictionary, which I built on the fly, but it was very slow. Does MongoDB have special features for such cases that might help?

+4
source share
2 answers

There is no single command you can use to do this, but you can do it with count:

 var doc = db.pages.findOne(); // Or however you get your document var n = db.pages.find({user_count : {$gt : doc.user_count}}).count(); // This is the number of documents with a higher user_count var ranking = n+1; // Your doc is next in a ranking 

A separate question is whether you should do this. Consider the following:

  • You will need the user_count index. You may already have this.
  • You will need to complete a counting request for each record displayed. There is no way to dose them.

Given this, you can affect your performance more than if you saved the rating in the collection depending on the CRUD profile of your application - it is up to you to decide which is the best option.

+3
source

There is no easy approach to solve this problem with MongoDB . If possible, I would advise you to take a look at Redis with Sorted Sets . As the documentation says:

With the help of Sorted Sets you can: take the leaderboard in a massive online game, where every time you get a new score, you update it with ZADD . You can easily take the top users using ZRANGE , you can also, given the username, return your rank to the list using ZRANK . Using ZRANK and ZRANGE together, you can show users with an account similar to that user. Everything is very fast.

You can easily get ranks for random pages using the MULTI/EXEC block. So this is the best approach to your task, I think, and it will be much faster than using MapReduce or retransmission using mongodb.

+1
source

Source: https://habr.com/ru/post/1493974/


All Articles