These are chat archives for Automattic/mongoose

28th
Feb 2018
Lamp
@ledlamp
Feb 28 2018 00:23
i am having a problem with finding documents with strings with special characters like # and &
Kev
@lineus
Feb 28 2018 00:32
if you have a gist of what you're working with, I'll take a look.
@ledlamp
Jan Dočekal
@violetzie
Feb 28 2018 11:51
Hello, just wanted to ask cause Im thinking about this right now.. what would be the most appropriate or efficient way of querying for 10 + 1 users based on their score points.. lets say every user has score form 0 to whatever number, I know how to get a top 10 with descending scores, thats great.. but I also want to include the current user and his score (no matter what position he is in, even if he is or is not in the top 10), should that be a separate query or can I somehow do that in one?
Mihajlo Ilijić
@Pritilender
Feb 28 2018 12:43
@violetzie maybe you can do that with aggregate and $facet, having two pipelines https://docs.mongodb.com/manual/reference/operator/aggregation/facet/
But I think that's a bit of an overkill...
Two queries are fine for something this small. And maybe you can cache current leader in Redis or whatever cache DB you're using.
Sorry, misinterpreted that you want TOP + leaderboard page.
And you want current + top 10.
Jan Dočekal
@violetzie
Feb 28 2018 12:50
@Pritilender yea basically I have a "game" and I want to display a top10 playerboard but also displaying the position of the currently logged in player to them in the board. So I log in, I see that these 10 people are top 10 and under it I see another field with my name and position like 310 or whatever
Mihajlo Ilijić
@Pritilender
Feb 28 2018 12:50
Anyhow, you can cache top 10 in Redis maybe if speed is of great importance. But if you're just for Mongo, than you can consider firing two queries in parallel with Promise.all, like this:
const top10Promise = Users.sort('points').limit(1).select('points name') // I guess you want names with this info
const currentPromise = User.findById(state.user.id).select('points') // state.user is where you'll have your current user's info stored
const [top10, current] = await Promise.all([top10Promise, currentPromise])
// transform top10 and current into some object, or whatever you need
Jan Dočekal
@violetzie
Feb 28 2018 12:51
oh, ok, thx for the tip on promise.all Ill try that, I guess that running 2 queries might be the best in the end
Mihajlo Ilijić
@Pritilender
Feb 28 2018 12:51
Do you want that info in real time or it's ok to be "cached" like you'll see it only when user opens leaderboard screen?
Jan Dočekal
@violetzie
Feb 28 2018 12:52
it doesnt have to be real time like real time, but it will be updated with a request every now and then
like Im gonna have an ajax or something there pulling new scoreboard every 5 seconds or something :)
Mihajlo Ilijić
@Pritilender
Feb 28 2018 12:52
Sorry, I wanted to ask you will you pull down whole scoreboard or just top 10?
If you're going with that often, I'll suggest using Redis for caching leaderboard.
Jan Dočekal
@violetzie
Feb 28 2018 12:53
Well I wanted to minimize the data requirements and not send everything so thats why I was asking about streamlining the query.. since I believe its better to send 10 records than 1000 if Im gonna display only 10 (or actually 11)
Mihajlo Ilijić
@Pritilender
Feb 28 2018 12:53
Like when your server starts, you do that User.sort('points') query, load all users into Redis, and then on any points change, update the cache.
Jan Dočekal
@violetzie
Feb 28 2018 12:54
oh ok, I never actually used Redis, I have to check that out
Mihajlo Ilijić
@Pritilender
Feb 28 2018 12:54
It's just in-memory cache. And pretty fast. I guess for 5s reads it's better maybe to use it. But if you're going to have maybe 1min reads, than Mongo is just fine.
Jan Dočekal
@violetzie
Feb 28 2018 12:55
Yea i see, thanks, seems like a great tip, im planning on having a bunch of polling actually so it might get used for other things too
Mihajlo Ilijić
@Pritilender
Feb 28 2018 12:55
And if you store your whole leaderboard in Redis, you can easily query it for current user and top 10 users. And it will probably be faster than running two queries in Mongo for this.
Sorry for asking, but why polling? Why not sockets?
Jan Dočekal
@violetzie
Feb 28 2018 12:56
sockets seemed a bit like an overkill
Mihajlo Ilijić
@Pritilender
Feb 28 2018 12:57
But you're just simulating "real-time" communication with polling instead of having it with sockets.
Jan Dočekal
@violetzie
Feb 28 2018 12:58
well I did think about using sockets but there are basically two parts of the app that are "real-time"-ish, one is the scoreboard and the other one is an events feed (like something in the game happened), otherwise the game itself is almost static, theres images that you have to drag to some categories, which gives you points or takes points from you
and I have a really tight schedule for the development, but if you have a recommendation for an easy to pick up socket library which I could implement fast, Im happy to give it a go and happy for any advice
I was also worried about mongo connections while using sockets, cause Im using the mongoDB Atlas and there are connection limits
but maybe I just understand it wrong
Mihajlo Ilijić
@Pritilender
Feb 28 2018 13:04
Ok, are those events something that should be communicated to everyone in the game?
Because it looks like you have typical use-case for sockets, but if server only needs to notify the clients when leaderboard is updated, then polling is fine.
Jan Dočekal
@violetzie
Feb 28 2018 13:05
yea
Mihajlo Ilijić
@Pritilender
Feb 28 2018 13:05
Well that's typical publish-subscribe pattern :D
Jan Dočekal
@violetzie
Feb 28 2018 13:05
everyone should for example see that "user XYZ just got 200 points and got the 5th place in leaderboard"
hmmm
:D
Mihajlo Ilijić
@Pritilender
Feb 28 2018 13:06
I worked with native sockets only, and they're pretty simple. What you would need is to have some message interface like: { type: string, data: any }. Your client (and server, if ever needed) will know how to respond to different types of messages.