What would be the best way to count demographics from DB? Mongoose+MongoDB - mongodb

I would like to present in my application's admin-pannel a count of the users demographics.
For example:
United States: 500 users
United Kingdom: 241 users
India: 2141241221 users.
Israel: 1 user.
Since there are a lot of countries in the world, I don't want to start searching for each country specifically. I would like to run one search that will count how many times each country appeared. I can't think of an idea that would not require me to search for countries specifically.
Example of what I do NOT want to do:
mongoose.find({Country: India}).then((documents) => { console.log("documents.length")} )
Using this method will require me to write the same line for each country that exists, and I'm sure theres a better way to go about it.

Use Mongodb Aggregation $group stage to achieve this.

Related

Mongo DB sort behavior

Let's say we have a collection of invoices and that we query and sort by sales date.
There can of course be many invoices on the same date.
Does Mongo provide any guarantee consistent order of the invoices for the same date?
e.g. does it also provide a default sort on say _id, or is the behavior described as undefined?
If one were to run the same query multiple times, would the invoices on the same date come in the same order each time?
Or is it up to the developer to also provide a secondary sort property, eg. _id. ?
To me, it looks like it is consistent, but can I really count on that?
1.Does Mongo provide any guarantee consistent order of the invoices for the same date?
Yes, results will be consistent all the time
Does it also provide a default sort on say _id, or is the behavior described as undefined?
By default all records will be sorted by `_id`, that's why i can say Yes to your first question.
If one were to run the same query multiple times, would the invoices on the same date come in the same order each time?
yes, always
is it up to the developer to also provide a secondary sort property, eg. _id. ?
yes
For my experiment results check attached screenshots.

How do I do sort based on specific position within an Array with MongoDB?

My usecase is this:
I have a collection of People who want to move to certain cities:
People {
cities: ['London', 'Denver', 'Tokyo']
}
The order of the cities tells me which city they prefer the most to least. The above person prefers to be in London the most.
I have a Landlord who has houses to rent out. And this guy is from one city, say London.
I have this Landlord in hand and I want to query the People collection and get back all the People in order of how much they prefer the landLord's city. So for this Landlord, everyone who prefers London the most should show up first, followed by everyone who like London second-best, etc.
For a different Landlord, say one from Denver, the sort would change to give people who like Denver the most.
Any way to do this in Mongo itself?
As far as the way your DB is set up now, I think the best you could do is query based on the 1st item in the Array. So the landlord will pass his location (London in this example) to this method call.
// As an example
db.people.find({ "cities.0" : "London" })

Efficiently find users using $near and excluding those who have disliked the user

Here is the assumed schema I think is the best to put into place
Users
userId
first_name
age
gender
location (lat,lon)
Matches
userId (voter)
like (vote)
liked_UserId
I know how to find users using the near parameter:
db.users.find({loc: {$near:[-180,40]}}).limit(3)
BUT
1) I'm trying to figure out the best and efficient way of finding users who are the closest and excluding users who have disliked this user. Should I make two query calls??? maybe a $where clause from the other collection somehow?
Edit: I'm thinking make one query to get all the users who have disliked this certain user, then add this array of users as part of a second query in the $nin...but will that be very slow if there are over 400,000 entries?
2) Does Tinder show the user of a profile of another user that disliked them?

how to join a collection and sort it, while limiting results in MongoDB

lets say I have 2 collections wherein each document may look like this:
Collection 1:
target:
_id,
comments:
[
{ _id,
message,
full_name
},
...
]
Collection 2:
user:
_id,
full_name,
username
I am paging through comments via $slice, let's say I take the first 25 entries.
From these entries I need the according usernames, which I receive from the second collection. What I want is to get the comments sorted by their reference username. The problem is I can't add the username to the comments because they may change often and if so, I would need to update all target documents, where the old username was in.
I can only imagine one way to solve this. Read out the entire full_names and query them in the user collection. The result would be sortable but it is not paged and so it takes a lot of resources to do that with large documents.
Is there anything I am missing with this problem?
Thanks in advance
If comments are an embedded array, you will have to do work on the client side to sort the comments array unless you store it in sorted order. Your application requirements for username force you to either read out all of the usernames of the users who commented to do the sort, or to store the username in the comments and have (much) more difficult and expensive updates.
Sorting and pagination don't work unless you can return the documents in sorted order. You should consider a different schema where comments form a separate collection so that you can return them in sorted order and paginate them. Store the username in each comment to facilitate the sort on the MongoDB side. Depending on your application's usage pattern this might work better for you.
It also seems strange to sort on usernames and expect/allow usernames to change frequently. If you could drop these requirements it'd make your life easier :D

Index vs aggregation

I have a collection of document - events - that have venues/addresses:
venue: {
name: String,
street: String,
city: String
...
}
When the user creates a new event I would like to offer an autocomplete field for the venue - ideally ordered by city if I can determine the user's location beforehand.
I see that Mongo offers a few methods of managing data from simply searching the collection, aggregation etc.. What would be the recommended approach for my situation?
If I index the event collection - when do I need to be concerned about the speed of search?
And for aggregation... I've not used it before but it seems a good fit especially with geo search but I am unclear as to when aggregation occurs. Is this something that is automatically done/populated once I set it up or do I need to run a cron job on this. Examples I am finding are unclear on this.
Would love to hear experiences people have with similar issues.
Aggregations are just a more sophisticated version of a query - just like in SQL you can do SELECT * from T1 or SELECT foo, count(*) from T1 GROUP BY foo so your question about cron jobs isn't really applicable unless you want to query something that's intensive to compute and you want to pre-compute it periodically.
When you index the fields that you query on, the result is the query will run much faster than an unindexed query - just like in RDBMS if you are familiar with those.
It sounds like you want to make a query based on what the user has already typed in. If I'm in San Francisco, CA and I started typing "S" in the venue field, presumably you want to run the query db.venues.find({city:"San Francisco",name:/^S/}) which would mean "venue in the city of San Francisco, name starting with 'S'."
I suspect you should save coordinates so that you can use geo-spacial search features in MongoDB - then you would get matching results sorted by closest to furthest from the coordinates that the user set as their location.
You can do this with a query so I don't see that you need an aggregation but it's possible that you would use aggregation to do various analysis of venues - the same queries are supported there, along with other powerful data manipulation operations.