How to pass complex get query parameters such as where order etc into GET https://firestore.googleapis.com/v1beta1/{name=projects/*/databases/*/documents/*/**}(firestore docs) ?
You can order and limit data in a Cloud Firestore query after using the Get Data method like this:
myDinoRef.where("type", "==", "TREX").orderBy("size", "desc").limit(2)
This will return all TRex Dinos and order by descending "size". It will also limit the result set to two rows.
Google's documentation is pretty good and ever evolving. It's also important to point out that the Cloud Firestore is still in beta (as of today)
Related
I am new to MongoDB. And I have the following issue on currently developing web application.
We have an application where we use mongoDB to store data.
And we have an API where we search for the document via text search.
As an example: if the user type “New York” then the request should send the all the available data in the collection to the keyword “New York". (Here we call the API for each letter typed.) We have nearly 200000 data in the DB. Once the user searches for a document then it returns nearly 4000 data for some keywords. We tried with limiting the data to 5 – so it returns the top 5 data, and not the other available data. And we tried without limiting data now it returns hundreds and thousands of data as I mentioned. And it causes the request to slow down.
At Frontend we Bind search results to a dropdown. (NextJs)
My question:
Is there an optimizing way to search a document?
Are there any suggestions of a suitable way that I can implement this requirement using mongoDB and net5.0?
Or any other Implementation methods regarding this requirement?
Following code segment shows the query to retrieve the data to the incomming keyword.
var hotels = await _hotelsCollection
.Find(Builders<HotelDocument>.Filter.Text(keyword))
.Project<HotelDocument>(hotelFields)
.ToListAsync();
var terminals = await _terminalsCollection
.Find(Builders<TerminalDocument>.Filter.Text(keyword))
.Project<TerminalDocument>(terminalFeilds)
.ToListAsync();
var destinations = await _destinationsCollection
.Find(Builders<DestinationDocument>.Filter.Text(keyword))
.Project<DestinationDocument>(destinationFields)
.ToListAsync();
So this is a classic "autocomplete" feature, there are some known best practices you should follow:
On the client side you should use a debounce feature, this is a most. there is no reason to execute a request for each letter. This is most critical for an autocomplete feature.
On the backend things can get a bit more complicated, naturally you want to be using a db that is suited for this task, specifically MongoDB have a service called Atlas search that is a lucene based text search engine.
This will get you autocomplete support out of the box, however if you don't want to make big changes to your infra here are some suggestions:
Make sure the field your searching on is indexed.
I see your executing 3 separate requests, consider using something like Task.WhenAll to execute all of them at once instead of 1 by 1, I am not sure how the client side is built but if all 3 entities are shown in the same list then ideally you merge the labels into 1 collection so you could paginate the search properly.
As mentioned in #2 you must add server side pagination, no search engine can exist without one. I can't give specifics on how you should implement it as you have 3 separate entities and this could potentially make pagination implementation harder, i'd consider wether or not you need all 3 of these in the same API route.
I would like to create two queries, with pagination option. On the first one I would like to get the first ten records and the second one I would like to get the other all records:
.startAt(0)
.limit(10)
.startAt(9)
.limit(null)
Can anyone confirm that above code is correct for both condition?
Firestore does not support index or offset based pagination. Your query will not work with these values.
Please read the documentation on pagination carefully. Pagination requires that you provide a document reference (or field values in that document) that defines the next page to query. This means that your pagination will typically start at the beginning of the query results, then progress through them using the last document you see in the prior page.
From CollectionReference:
offset(offset) → {Query}
Specifies the offset of the returned results.
As Doug mentioned, Firestore does not support Index/offset - BUT you can get similar effects using combinations of what it does support.
Firestore has it's own internal sort order (usually the document.id), but any query can be sorted .orderBy(), and the first document will be relative to that sorting - only an orderBy() query has a real concept of a "0" position.
Firestore also allows you to limit the number of documents returned .limit(n)
.endAt(), .endBefore(), .startAt(), .startBefore() all need either an object of the same fields as the orderBy, or a DocumentSnapshot - NOT an index
what I would do is create a Query:
const MyOrderedQuery = FirebaseInstance.collection().orderBy()
Then first execute
MyOrderedQuery.limit(n).get()
or
MyOrderedQuery.limit(n).get().onSnapshot()
which will return one way or the other a QuerySnapshot, which will contain an array of the DocumentSnapshots. Let's save that array
let ArrayOfDocumentSnapshots = QuerySnapshot.docs;
Warning Will Robinson! javascript settings is usually by reference,
and even with spread operator pretty shallow - make sure your code actually
copies the full deep structure or that the reference is kept around!
Then to get the "rest" of the documents as you ask above, I would do:
MyOrderedQuery.startAfter(ArrayOfDocumentSnapshots[n-1]).get()
or
MyOrderedQuery.startAfter(ArrayOfDocumentSnapshots[n-1]).onSnapshot()
which will start AFTER the last returned document snapshot of the FIRST query. Note the re-use of the MyOrderedQuery
You can get something like a "pagination" by saving the ordered Query as above, then repeatedly use the returned Snapshot and the original query
MyOrderedQuery.startAfter(ArrayOfDocumentSnapshots[n-1]).limit(n).get() // page forward
MyOrderedQuery.endBefore(ArrayOfDocumentSnapshots[0]).limit(n).get() // page back
This does make your state management more complex - you have to hold onto the ordered Query, and the last returned QuerySnapshot - but hey, now you're paginating.
BIG NOTE
This is not terribly efficient - setting up a listener is fairly "expensive" for Firestore, so you don't want to do it often. Depending on your document size(s), you may want to "listen" to larger sections of your collections, and handle more of the paging locally (Redux or whatever) - Firestore Documentation indicates you want your listeners around at least 30 seconds for efficiency. For some applications, even pages of 10 can be efficient; for others you may need 500 or more stored locally and paged in smaller chucks.
Hi Im using cloud firestore and flutter. I want to query firestore in a way that i will get one by one element from the query and not all at once. Im developing a card game when the user will draw cards from a deck and can decide when to stop, so i don't want to query more than I the user needs to. Im looking at startAtDocument() that might be a solution but not sure what will be the best practice.
If you want to limit a query to return at most one document, you can just .limit(1) to the end of your query. See the documentation on the Query.limit method.
If you later want to get one or more additional documents, you'd use Query.startAfterDocument passing in the document you already have. The query will then return documents after the so-called anchor document that you're passing in.
I need to query my Cloud Firestore database periodically for maintenance. I'm new to REST and I've spent way too long trying to solve this myself, so I figured I could use some advice.
My Firestore is set up like so:
users > {uid} > uploaded-files > {file-hash}
{file-hash} is a document that contains several fields such as filename, source, and size
All I'm trying to do is get a list of every single filename from every single uploaded-file, including from multiple {uid}'s.
I've managed to send a successful request and get a single filename using the firestore.projects.databases.documents.get method using the API explorer, but I can't seem to get any other methods to work, namely firestore.projects.databases.documents.list
This is the successful request using firestore.projects.databases.documents.get:
GET https://firestore.googleapis.com/v1beta1/projects/{project-id}/databases/(default)/documents/users/7eGfdgGfaG0HSXdfmxMN2/uploaded-files/WGtcJBX9fdGdhdtjB?mask.fieldPaths=filename&key={YOUR_API_KEY}
Part of my issue is that I can't figure out how to get requests to work without hard-linking document names - in other words, I don't know how to to replace {uid}, or any other collection, with a wild-card so that the request returns documents from all uid's.
Really any help is greatly appreciated.
The Use the Cloud Firestore REST API documentation has instructions on getting started. The Firestore REST API documentation shows how to fetch documents.
In your case you would need to list the user-uid documents then go after the uploaded-files for each one, or iterate over the results of the list.
Is there a way to query by document id in WDS? I've tried things like
id:"9cdd3db8-b127-4176-b727-b31bf86870fc"
id:9cdd3db8-b127-4176-b727-b31bf86870fc
Neither of these work. I'm doing some testing, and I'd like to guarantee that I can get back a specific document.
Use a filter parameter _id:9cdd3db8-b127-4176-b727-b31bf86870fc
reference on IBM DVW