How to create search that shows results from multiple firestore collections in Flutter? - flutter

I have 2 different Firestore collections namely 'restaurants' and 'dishes'.
I currently have created 2 separate searches where user either searches for a dishes in search1 connected to 'dishes' collection or a dish in search2 connected to 'dishes' collection.
Please suggest on how to have just one search which searches in both collections in the backend and shows results from both 'restaurants' and 'dishes' at one place. Something like a universal search. So if user types 'burger' it should show 'chicken burger dish' as well as 'burger kind restaurant'.
Was able to make the searches work independently but need help with the strategy to combine the search in to one.
Thanks for your help.

Please suggest how to have just one search which searches in both collections in the backend and shows results from both 'restaurants' and 'dishes' in one place.
There is currently no way in which you can perform a search in two different collections at the same time. Why? Because the queries in Firestore are shallow, meaning that they only get documents from the collection that the query is run against. So to solve this, you have to perform two separate queries.
There is a workaround that might help, which would be to add all the necessary data on which you want to perform the search in a single document, most likely into a field of type array. In that way, you can perform a search using the "array contains" operator. Or for small datasets to search using contains.
If the above solution doesn't work for you, then you have to implement a third-party search service, as mentioned in the official documentation.

Related

Query multiple subcollections firestore flutterfire

Im working on a project using flutter and firebase, currently the database(firestore) has A collection named Projects, each project has an owner(userId) and a subcollection named Sections and each section has an Items collection. Each Item has a list of tags (strings). I wanted to add a search Items by tag feature, but just realized that the nested collections structure makes it hard. Changing the database structure now would be a lot of work. Is there a way to apply a query to multiple subcollections? basically I would need to query all projects owned by the user then query for all in those projects sections and then all todos inside them that contain a certain tag.
I don`t want to do multiple queries and join them with frontend code because I'm using real time functionality and having to deal with multiple streams isn't ideal. Cloud functions aren't an option right now because I'm using the free plan.
You're looking for a so-called collection group query, which searches across all collections with a certain name in one go.

Firestore pagination of multiple queries

In my case, there are 10 fields and all of them need to be searched by "or", that is why I'm using multiple queries and filter common items in client side by using Promise.all().
The problem is that I would like to implement pagination. I don't want to get all the results of each query, which has too much "read" cost. But I can't use .limit() for each query cause what I want is to limit "final result".
For example, I would like to get the first 50 common results in the 10 queries' results, if I do limit(50) to each query, the final result might be less than 50.
Anyone has ideas about pagination for multiple queries?
I believe that the best way for you to achieve that is using query cursors, so you can better manage the data that you retrieve from your searches.
I would recommend you to take a look at the below links, to find out more information - including a question answered by the community, that seems similar to your case.
Paginate data with query cursors
multi query and pagination with
firestore
Let me know if the information helped you!
Not sure it's relevant but I think I'm having a similar problem and have come up with 4 approaches that might be a workaround.
Instead of making 10 queries, fetch all the products matching a single selection filter e.g. category (in my case a customer can only set a single category field). And do all the filtering on the client side. With this approach the app still reads lots of documents at once but at least reuse these during the session time and filter with more flexibility than firestore`s strict rules.
Run multiple queries in a server environment, such as cloud store functions with Node.js and get only the first 50 documents that are matching all the filters. With this approach client only receives wanted data not more, but server still reads a lot.
This is actually your approach combined with accepted answer
Create automated documents in firebase with the help of cloud functions, e.g. Colors: {red:[product1ID,product2ID....], ....} just storing the document IDs and depending on filters get corresponding documents in server side with cloud functions, create a cross product of matching arrays (AND logic) and push first 50 elements of it to the client side. Knowing which products to display client then handle fetching client side library.
Hope these would help. Here is my original post Firestore multiple `in` queries with `and` logic, query structure

A collection within a collection

I just wanted to query everyone's best practice for doing this.
User has multiple notebooks within their account. Each of these is a record in the database.
There are multiple users.
The notebook has different sections to fill in. There are also sections which are lists. The user needs to be able to add extra items to these lists (almost as if it were it's own collection).
There may be a lot of users, and I want all their notebooks in the same collection.
How would you approach this? I'm using Simple Schema and Aldeed Collection. I imagine that each list within the notebook would be an array, but how would I make it that the user can set how many items / add new items to the list?
Interested to know people's thoughts!
This is a MongoDB data modeling question primarily (see also schema design), but there are a few things to keep in mind with Meteor:
read up on reactive joins at Discover Meteor and Gentle Node
for reactivity to work at its best, you want collections instead of arrays
that means you'll need to perform the equivalent of joins with MongoDB, so have a look at reactive join packages, this post about evaluating them, and Meteor.publish: publish collection which depends on other collection
Make sure to vote up this card on the Meteor roadmap to get native reactive joins.

MongoDB database design - contest application

I'm building a contest application. Which have 4 collections so far:
contest
questions
matches
users
I want to store every user score for every match he's assigned into. But I really can't find a proper way to achieve this.
All what I've came up with, Is to replace matches in users with an array in which each element contains a reference to matches collection and score field. But I think this is not very efficient.
EDIT
I was thinking about another solution. A separate collection called scores that contains three fields user, match and score.
Here's my schema structure:
Contests:
Questions:
Matches:
Users:
Note Any recommended adjustments on the current design is welcomed too.
Since mongodb is not designed to support collections relationships you migth end up with some duplicated work, I would suggest you to find a way of storing as much data as you can in a single document.
Your scores would go in each match document, probably the users array would have this structure {'users':[{user_id:'xxx',score:xxx}{user_id:'xxx',score:xxx}]}
The other solution, would be what you say, to have in each user doccument, a matches array with a structure like this: {'matches':[{match_id:'xxx',score:xxx}{match_id:'xxx',score:xxx}]}
You can have both also, this migth be more efficient depending the kind of queries you will need to do. You can also have a field in the subdocuments that stores the user/match name/title
Note: As you can see, you have two solutions, or you optimize for doccument size(so you can store more) or you optimize for performance (so you can read faster/with less resources)
Hope this be of any help.

"Pointers" in MongoDB?

In the project I am currently working on, it seems to make more sense efficiency wise if I create a nested document that contains a list of "pointers" to information stored in other collections. That way this nested document can be easily used to retrieve a list of relevant information. The question is, how to do this? Is there a way to store locations of other information in a field in MongoDB? If not, could anyone suggest a scheme that is equally or more efficient? Thanks very much!
There is no GOOD way to do this. If this is what you're looking for, you should be using a relational database.
But if you HAVE to go by this route then, why not store ID's in a document, and then link those ID's to documents in the other collection.
Unfortunately, this would require you to do 2 separate queries, as Mongo does not support compound queries that span documents.