firebase Deep collectionGroup query in firestore - google-cloud-firestore

I have a collection structure in Firestore that looks like:
/teams/**/days/**/milestones/**
/teams/1WCraAZXLSNSoMvkZuSV/days/20210822/milestones/xyzdocid
So, I would have a set of documents in the milestones collection at the end. I'm trying to query milestones as a collectiongroup. How do I setup a collectionGroup index for this?
Is this too deep for the collectionGroup to work? What does the index look like for this? Is it possbile to create this collectionGroup index in the firebase emulator?

To anybody running into this same problem:
In the Emulator, collectionGroups and all index related operations automatically work. You don't need to setup anything special. This wasn't very well documented. I spent quite some time trying to find out how to create an index in the emulator. This also means, that you will need to do quite a bit of testing with a live firebase account, because most things will not automatically work there.
The collectionGroup format is based on the name of the collection only and not your indexes or any kind of paths. Meaning, if you have collections called "milestones" anywhere in your structure, the collectionGroup concept will combine them together. This is very powerful, but be careful about collections / subCollections with the same name but different purpose.

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.

How to create search that shows results from multiple firestore collections in 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.

How to connect to a collection in mongodb

I want to use the collections as DBs!.. make a connection from nodejs where you can use a collection as a normal database.??
The purpose of this is that I'm going to create two totally different apps, with different collections and documents, but there are data that I need to relate between the two apps. And if the two apps are using the same database, it would be much easier for me.
Well.. MongoDB doesnt do that, what can you do is something like give a prefix name to your collections, "projectA_Users , projectB_Users" and to relate data use the $lookup Aggregate operator to get your relationship. I see something like that on FireBase that you can create a collection inside a document and use find, update, remove on it (here)

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.

How to store query output in temp db?

I am really new to the programming but I am studying it. I have one problem which I don't know how to solve.
I have collection of docs in mongoDB and I'm using Elasticsearch to query the fields. The problem is I want to store the output of search back in mongoDB but in different DB. I know that I have to create temporary DB which has to be updated with every search result. But how to do this? Or give me documentation to read so I could learn it. I will really appreciate your help!
Mongo does not natively support "temp" collections.
A typical thing to do here is to not actually write the entire results output to another DB since that would be utterly pointless since Elasticsearch does its own caching as such you don't need any layer over the top.
As well, due to IO concerns it is normally a bad idea to write say a result set of 10k records to Mongo or another DB.
There is a feature request for what you talk of: https://jira.mongodb.org/browse/SERVER-3215 but no planning as of yet.
Example
You could have a table of results.
Within this table you would have a doc that looks like:
{keywords: ['bok', 'mongodb']}
Each time you search and scroll through each result item you would write a row to this table populating the keywords field with keywords from that search result. This would be per search result per search result list per search. It would probably be best to just stream each search result to MongoDB as they come in. I have never programmed Python (though I wish to learn) so an example in pseudo:
var elastic_results = [{'elasticresult'}];
foreach(elastic_results as result){
//split down the phrases in this result and make a keywords array
db.results_collection.insert(array_formed_from_splitting_down_result); // Lets just lazy insert no need for batch or trying to shrink the amount of data to one go or whatever, lets just stream it in.
}
So as you go along your results you basically just mass insert as fast a possible create a sort of "stream" of input to MongoDB. It can do this quite well.
This should then give you a shardable list of words and language verbs to process things like MRs on and stuff to aggregate statistics about them.
Without knowing more and more about your scenario this is pretty much my best answer.
This does not use the temp table concept but instead makes your data permanent which is fine by the sounds of it since you wish to use Mongo as a storage engine for further tasks.
Actually there is MongoDB river plugin to work with Elasticsearch...
db.your_table.find().forEach(function(doc) { b.another_table.insert(doc); } );