I'm looking for the most simply designed database structure for a given day, food type, food name and food price.
The part that is giving me trouble is, I feel like, the food name and food price need to be "tied together".
The pictures below are what I have experimented with, but I feel like I am over engineering the structure.
I think you need to understand the firebase ideas of collections and document better - this two level structure is often confusing to developers more familiar with SQL-like databases.
A document contains fields and potentially collections. A collection is always a collection of documents.
So in your case you might make a collection called days which contains documents 'monday','tuesday'....
the monday document might contain some other fields (the chef, the date ect) and a collection (of documents) called 'dessert'
Then each of your dessert documents might include fields for description, price etc.
So in general if you are trying to define a list of multiple similar objects your are wanting a collection of documents. If you are wanting to define fields within an object you should be looking to store them in a document.
Related
I am very new to SPAs (Single Page Applications) and noSQL coding, but I am very interested in these topics!
I do have experience with PHP, mySQL & relational Databases which is messing with my mindset when developing with a noSQL database.
I am currently developing a webapp where i create a collection called 'campaigns'.
This collection has a subcollection called 'categories'.
Which has another subcollection called 'notes'.
The Firestore setup is like this:
Campaigns
campaign1
Categories
category1
Notes
note1
note2
campaign2
Categories
category1
Notes
note1
note2
At the moment when I want to display note1 I have to create the URL like this:
domain.com/campaigns/Wi8AyzYgpKCnTXvCL9SV/categories/XlsMW4a8YRoLC1t3NbWG/notes/wg5oGQIZ8EOSYdFVOIlB
This seems a bit overkill.
Is there a way to shorten it to something like this:
domain.com/notes/wg5oGQIZ8EOSYdFVOIlBm
I know this can be done in a relational database, but I don't know if it can be done with Firestore
One solution would be to have a flat notes root collection with all the notes documents which have a campaign and category fields.
This way you can directly extract the document id from an url like domain.com/notes/wg5oGQIZ8EOSYdFVOIlBm. If you want to query for a specific campaign or category or a specific campaign/category couple, you just use a where() query (or a combination of tho where()s).
In terms of performance it will make no difference compare to a sub-collection approach as described in your question: the execution time for a query depends on the number of docs returned by the query.
Is there a way to aggregate recurring document property in a collection from a query?
For example, a car collection contains a list of documents with carMake and carMakeModel. The property carMake can contain Honda, Ford, Toyota, and so on... while carMakeModel contains the model of the car i.e. Civic, Prius...
With that sample, is there a way to query car collection displaying only carMake and aggregating similar entries so it won't appear again on the query result?
What I'm currently doing at present is maintaining a separate carMake collection. I'm curious if there's something more efficient than that.
While it is possible to read all cars and then aggregate the makes, the problem with that is that you'll have to do it in your application code. Firestore does not have server-side aggregation capabilities built-in.
The common solution to prevent reading all cars to determine the makes (which typically is much less data), is precisely what you're doing: storing a separate document or collection with just the list of car makes.
To keep this derived list of car makes up to date, you can either write them from client-side code whenever you also write a car, or you can use Cloud Functions to trigger automatically when a car is written and then update the corresponding make.
A newbie here.
I need help regarding Firebase sub collection referencing in a structured way where a user can select and pass information through sub collection.
=> Tournaments => Cities => Cairo => Year => High Goal => Team A
That goes like this from the root I have a list of cities let’s say
1. Cairo
2. Alexandria
3. Sixth October
I want to keep record of tournaments hosted each year by these cities based on years. Let’s say
a.
1. 2019
2. 2018
3. 2017
Each year there are 3 different competed cups let’s say
1. High goal
2. Medium goal
3. Low goal
Every competed cup has teams that participate in the tournament
1. Team A
2. Team B
3. Team C
I have added a visual representation of the app designed in adobe XD.
Data modeling for NoSQL databases depends as much on the use-cases of your app as it depends on the data that you store. So there is no "perfect" data model, nor are there nearly as many best practices (or normal forms) for NoSQL databases are there are for relational data models.
Firestore (which you seem to be looking to use), offers a few tools for modeling data:
The discrete unit of storage is called a document. Each document contains fields of various types, including nested fields, and a document can be up to 1MB in size.
Documents are stored in named collections.
You can nest collections under a document, and build hierarchies that way.
Each document has a unique path of the form /collection1/docid1/collection2/doc2 etc.
To write to a document, you must know its exact path.
You can query a collection for a subset of the documents in there.
You can query across all collections with the same name, no matter their path in the database.
The performance of queries depends solely on the number of documents you retrieve, and not on the number of documents in the collection(s).
There are probably quite a few more rules, but these should be enough to get you started.
I typically recommend writing a list of your top 3-5 use-cases, and determining what reads/queries you need for that. With those queries, you can then start defining your data model, and implementing your application code.
Then each time you add a use-case, you figure out how to read/write the data for that use-case, and potentially change/expand the data model to allow for the new and existing use-cases. If you get stuck when adding a specific use-case, report back here and we can try to help.
Some good additional material to get started:
NoSQL data modeling
Getting to know Cloud Firestore
Firebase for SQL developers, which is for Firebase's other NoSQL database, but is a great primer on NoSQL modeling too.
Based on this other question and on this pricing list I have the next one:
What's the point of using collections when we have a limitation for reads, writes and deletes per document?
I have a collection with 2 different collections inside, would I increase everything x3?
Would it be better for moving everything to the first collection as a single document?
The Firestore pricing for reading ONE document is neither function of the collection (or sub-collection) containing the document nor function of the sub-collection(s) contained by the document.
As you can read in the SO answer/question you refer to, "Firestore queries are always 'shallow'", meaning that when you read a document, you pay for the document read but you don't pay at all for the documents that are in its sub-collection(s).
It's worth noting that the concept of sub-collection can be a bit "misleading".
Let's take an example: Imagine a doc1 document under the col1 collection
col1/doc1/
and another one subDoc1 under the subCol1 (sub-)collection
col1/doc1/subCol1/subDoc1
Actually, from a technical perspective, these two collections (col1 & subCol1) are not at all relating to each other. They just share a part of their path but nothing else. One side effect of this is that if you delete a document, its sub-collection(s) still exist.
So, to answer your questions:
I have a collection with 2 different collections inside, would I
increase everything x3?
It depends on what you exactly read. If you only read documents from the first (parent) collection, you will only pay for these document reads. You will only pay for the documents contained in the two sub-collections if you build two extra queries to read the documents in these 2 sub-collections. Again, you just have to consider these three (sub-)collections as totally independent and therefore you pay for each document you read in each of those collections.
Would it be better moving everything to the first collection as a
single document
It really depends on your data model and on the queries you plan to execute. It is totally possible to "move everything in a single document", but you should take care of some limitations, in particular, the maximum size for a document which is 1 MiB.
Also, if your data model contains some complex hierarchical data it may be much easier to organize this data using sub-collections within documents instead of using nested objects or arrays in one document. For example, querying documents through data contained in Arrays has some limitations.
Again, there isn't a "one single truth": it all depends on your specific case. Note that, in the NoSQL world, your data model should be mainly designed in the light of the queries you plan to execute, without hesitating to denormalize data.
The firestore docs don't have an in depth discussion of the tradeoffs involved in using sub-collections vs top-level collections, but do point out that they are less flexible and less 'scalable'. Given that you sacrifice flexibility in setting up your data in sub-collections, there must be some definite plus sides besides a mentally satisfying structure.
For example how does the time for a firestore query on a single key across a large collection compare with getting all items from a much smaller collection?
Say we want to query a large collection 'People' for all people in a family unit. Alternatively, partition the data by family in the first place into family units.
People -> person: {family: 'Smith'}
versus
Families -> family: {name:'Smith'} -> People -> person
I would expect the latter to be more efficient, but is this correct? Are the any big-O estimates for each?
Any other advantages of sub-collections (eg for transactions)?
I’ ve got some key points about subcollections that you need to be aware of when modeling your database.
1 – Subcollections give you a more structured database.
2 - Queries are indexed by default: Query performance is proportional to the size of your result set, not your data set. So does not matter the size of your collection, the performance depends on the size of your result set.
3 – Each document has a max size of 1MB. For instance, if you have an array of orders in your customer document, it might be a good idea to create a subcollection of orders to each customer because you cannot foresee how many orders a customer will have. By doing this you don’t need to worry about the max size of your document.
4 – Pricing: Firestore charges you for document reads, writes and deletes. Therefore, when you create many subcollections instead of using arrays in the documents, you will need to perform more read, writes and deletes, thus increasing your bill.
To answer the original question about efficiency:
Querying all people with the family 'Smith' from the people top-level collections really is not any slower than asking for all the people in the 'Smith' family sub-collection.
This is explained in the How to Structure Your Data episode of the Get to Know Cloud Firestore video series.
There are some trade-offs between top-level collections and sub-collections to be aware of. Depending on the specific queries you intend to use you may need to create composite indexes to query top-level collections or collection group indexes to query sub-collections. Both these index types count towards the 200 index exemptions limit.
These trade-offs are discussed in detail near the bottom of the Understanding Collection Group Queries blog post and in Maps, Arrays and Subcollections, Oh My! episode of the Get to Know Cloud Firestore video series.
I've linked to the relevant parts of both videos.
I was wondering about the same thing. The documentation mainly talks about arrays vs sub-collections. My conclusion is that there are no clear advantages of using a sub-collection over a top-level collection. Sub collections had some clear technical limitations before, but I think those are removed with the recent introduction of collection group queries.
Here are some advantages of both approaches:
Sub collection:
Your database "feels" more structured as you will have less top-level collections listed.
No need to store a reference/foreign key/id of the parent document, as it is implied by the database structure. You can get to the parent via the sub collection document ref.
Top-level collection:
Documents are easier to delete. Using sub collections you need to make sure to first delete all sub collection documents before you delete the parent document. There is no API for this so you might need to roll your own helper functions.
Having the parent id directly in each (sub) document might make it easier to process query results, depending on the application.
Todd answered this in firebase youtube video
1) There's a limit to how many documents you can create per minute in
a single collection if the documents have an always-increasing value
(like a timestamp)
2) Very large collections don't do as well from a
performance standpoint when you're offline. But they are generally
good options to consider.