Mongodb get document position in collection - javascript

Is there a way to get a document's position relative to its collection based on one of its properties in Mongodb?
The use case is that I am building a leaderboard, but want to provide an easy way for the user to know their rank without having to scroll through all the entries.
Is there some mongoose schema magic or mongodb query that will help me easily get the position of a user based on their score?
Currently, my solution is to create an index on the score, query the entire collection and find the index of the user in the result.

Strictly speaking, this is not possible, as MongoDB does not store its documents in any certain order. Your current approach should be fine.
You're not the first one with this question: there's a feature request for this exact thing with a high priority.
https://jira.mongodb.org/browse/SERVER-4588

Related

Is IndexedDB suitable for providing suggestions as user types input

Currently I have a website with an input element with an event listener that is fired by the input event. Any new input results in an Ajax request where an SQL query is made, which uses the LIKE keyword to find all records which have the contents of the input element as a substring. There can be as many as over a million records in the SQLite database.
I would like this to work for users when they are off line, so I have thought about using IndexedDB storage so they could download the data to their device when online and then use the system when they are offline. I did read at https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Basic_Terminology that
The API does not have an equivalent of the LIKE operator in SQL.
I have almost no experience in any databases other than SQL types. I would like to find out before getting too involved whether the IndexedDB API would be suitable for achieving the type of auto suggestion feature for user input that I have described.
IndexedDB essentially only allows you to retrieve objects by primary key or by a property that you have specifically created an index for. These will be exact match or range match lookups. You can't look inside strings for substring matches.
However, this does not mean that you should not use IndexedDB to store your data. It just means that you need a layer on top such as Elasticlunr.js which will build a search index. You can rebuild that index every time the database changes, and persist that search index to the database.

What's the best way to assign a priority to document (order) - Firestore

I have a collection of orders and by default I want to create a field called priority that, at the time of creation, is the size of the collection. That's the only way I can think of to get a auto-incrementing number in Firestore.
My only issue is that the orders get added via a batch write. So even if I fire off an onCreate cloud function, the possibility of querying the collection size and getting back the same value is, I think, high.
My reason for wanting the priority this way is because changing the priority is a dragging and dropping rows on a table on the front-end. I just swap the priorities and write the new priorities to Firestore. That way when the table is loaded up again, I can sortBy priority and deliver a sensible experience.
How can I get a unique, auto-incrementing number for this use case?
I know this is subjective, but I've spent way too much time thinking about this as it is.

Is there a way to push the results of a PostgreSQL query into a JavaScript array?

Just looking to see if there's an elegant solution to this problem:
Is there a way to loop through the results of a psql query and return a specific result based on the SQL query?
For example, let's say I wanted to SELECT amount_available FROM lenders ORDER BY interest_rate, and I wanted to loop through the column looking for any available amounts, add those available amounts to a variable, and then once that amount reached a certain figure, exit.
More verbose example:
Let's say I have someone who wants to borrow $400. I want to go through my lenders table, and look for any lender that has available funds to lend. Additionally, I want to start looking at lenders that are offering the lowest interest rate. How could I query the database and find the results that satisfy the $400 loan at the lowest interest rate, and stop once I've reached my goal, instead of searching the whole db? And can I do that inside a JavaScript function, returning those records that meet that criteria?
Maybe I'm trying to do something that's not possible, but just curious.
Thanks!
You translate your requirement into the SQL language. After all, SQL is a descriptive language. The database engine then figures out how to process the request.
Your example sound like
SELECT name
FROM lenders
WHERE property >= 400
ORDER BY interest_rate
FETCH FIRST ROW ONLY;

Alternative to collection group query

I am trying to write a https cloud function which pulls out specific documents from my cloud firestore. The initial collection is 'Message', however then there are various different sub collections. The path for each document I am trying to view is the following Message/{UserId}/{ChatRoomId}/{UserId_1}. One variable under each UserId_1 is 'creationTime' and I am trying to query for specific documents that satisfy such creationTime. The problem is I don't know how to solve it as I was told this requires the use of collection group queries, which are currently not available in the firestore. Any alternative suggestion?
What I would be trying to achieve in the end is a comparison of each document's creationTime with the current timestamp.
Update: As of May, 2019, Cloud Firestore now supports collection group queries.
As you mentioned, it is not possible at the time of writing to query across collections (the so called "collection group queries" are apparently under development, however).
So the only possibility seems to be a modification of your data model.
You could, for example, duplicate your data and have a collection for each creationTime (probably a Timestamp), under which you have one document for each triplet {UserId}/{ChatRoomId}/{UserId_1}

Firebase Firestore - Query for posts in a big collection where groupId should match a value in an array

I am having troubles with firebase using the cloudstore .where query.
I want to query a big collection of documents (in my case posts) but I only want to query the posts in which the groupId matches any of the groups that the user is in. The reason for this is that I want to query a combined feed for the user with all the latest relevant data (using orderBy and limit).
I know that I can use array-contains, so I could for instance query all of the posts for user where the user is a member.
firebase.db.collection('posts').where('members','array-contains',firebase.uid)
This would work if I decided to keep track of the members in a group. Problem is if I would change members in a group, I would have to loop through all posts and change the array of members (not really good practice). Better would then be to have the post contain and id of which group it was posted in.
So let's say the user has an array containing all the groups he is in
user.groups = ['companyGroup', '{id}', '{id2}']
I would then like to query through the whole posts collection and get all the documents where the field groupId matches any of the values in user.groups something like this:
firebase.db.collection('posts').where('groupId','==',[any of user.groups])
or maybe the reverse:
firebase.db.collection('posts').where(user.groups,'array-contains','groupId')
^ I have not tried this one but I am certain it doesn't work according to the docs according to
The where() method takes three parameters: a field to filter on, a comparison operation, and a value. The comparison can be <, <=, ==, >, >=, or array_contains.
Is there a possible way to do something like this? I can't really query multiple locations at once and combine them because that defeats the purpose of being able to limit the data and orderBy fields. I understand that I could put a new collection called feed under every user and for every post use a firebase function that pushes to post to the relevant members feed (only the id and latestActivity), but then as soon as that post changes (I am going to use a field called latestActivity to order data according to relevancy, but also when deleting a post) I would need to loop through all docs under every user affected and change the value/delete doc.
Any ideas are greatly appreciated!
Currently, there is no way to pass an array of ids to the where() function and expect to get all the documents that corresponde to each particular id:
firebase.db.collection('posts').where('groupId','==',[any of user.groups])
The option that you have, is to store in the array either the ids as strings or references (path to group documents). There is no real advantage of storing references rather than strings, so it's up to you to decide which one you feel more comfortable with.
To get the all group documents, you should get the array that contains those ids/references and for each one separately create a new database request. So unfortunately there is no other way to get those group documents at once using a single query.
However, creating extra database calls it doesn't mean that fetching, let's say 3 documents, will be 3x slower as fetching one document. You can make some tests yourself.
I quote #Frank van Puffelen, "Firebase has a history of performing fine in such cases, since it pipelines the requests."
use array contain it works perfectly.
firebase.db.collection('posts').where(user.groups,'array-contains','groupId')
it works pretty good for me . you should try this.

Categories

Resources