Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firestore subcollection vs array

First of, I know how Firestore works and have spent a lot of time, evaluating different approaches for a good structure. Still I am considering following scenario:

There is a database of known recipes. Users can add recipes, but they have to be confirmed to be real recipes and not just some variations. So every user can choose receipes from the user-generated list of recipes to state, that they know how to cook them (or add new ones).

Now I want users to share their list of receipes with others, but this is where I am not sure how this can be best accomplished using Firestore. The trick is, that I want to show all the recipes at once, and don't want to paginate them.

I am currently evaluating two possibilities:

Subcollections

Whenever a user shares his list, the user looking at said list will have to load the entire list of the recipes which can result in a high amount of document reads (I suppose realistically ~50, in very rare cases maybe 1000).

Pros:

  • More natural structure
  • Easier to maintain (e.g. deleting a recipe, checking if a specific one exists)
  • Easier to add fields (e.g. timeOfCreation, comment, personalRating, ...)

Cons:

  • Can result in a high amount of reads on the long run

Arrays

I could save every known recipe (the id and an imageURL) inside the user's document (or as a single subdocument "KnownRecipes") within an array. This array could be in form of

recipesKnown: [{rid: 293ndwa, imageURL: image1.com, timeAdded: 8371201332},                 {rid: 9012831, imageURL: image1.com, timeAdded: 8371201871},                {rid: jd812da, imageURL: image1.com, timeAdded: 8371201118},                ...               ] 

Pros:

  • I only need one document read whenever someone wants to see another user's list
  • Reading a user's list is probably faster

Cons:

  • It's hard to update a specific recipe (e.g. someone wants to change the imageURL: I need to change the list locally and send the entire document as an update to the server - since I cannot just change a single element in the array)
  • When a user decides to have around 1000 recipes (this will maybe never happen, but it could), the 1MiB limit of the Firestore limit could be reached. A possible workaround would be to create a seperate document and split those two arrays into these two documents.

For me, the idea with Subcollections seems to be the more "clean" solution to this problem, but maybe I am missing some arguments on why one of those solutions would be superior over the other.

My most common queries are as follows (ordered descending by importance):

  • Which recipes can a user cook
  • Add a recipe a user can cook to the user's list
  • Who can cook a specific recipe (there is a Recipe -> Cooks subcollection)
  • Update an existing recipe a user can cook
like image 711
Thomas Avatar asked Apr 30 '19 18:04

Thomas


People also ask

What is a Subcollection in firestore?

A subcollection is a collection associated with a specific document. Note: You can query across subcollections with the same collection ID by using Collection Group Queries. You can create a subcollection called messages for every room document in your rooms collection: collections_bookmark rooms.

Can firestore store arrays?

Firestore lets you write a variety of data types inside a document, including strings, booleans, numbers, dates, null, and nested arrays and objects. Firestore always stores numbers as doubles, regardless of what type of number you use in your code.

What is the limited depth of Subcollection in firestore?

I saw on the Firebase Firestore documentation that the limits for the "Maximum depth of subcollections" is 100.


2 Answers

The answer to your question depends on the level of scalability you want to achieve.

If by design the amount of sub-data you want to store is limited and very low, you should use arrays, since you reduce the number of document reads, which means lower costs.

If your sub-data is supposed to increase "unlimitedly" over time, you should use sub-collections.

If you're building a database which is not supposed to scale in any direction (Proof of concept, very small business, etc.) just go with what you feel more comfortable with.

like image 196
Alessio Canepa Avatar answered Oct 02 '22 17:10

Alessio Canepa


I'm researching the same question...

One of the questions is whether the data held in the document will be ever go pass 1MB that is the limit for a document. Researching a bit on how much it can be held in plain text in 1MB well it's a hell of a lot. Still if it were to be incredible bigger it would crash in the end. Thus if you think in a big-big way sub-collections.

If we had to use the Firebase element logic the answer would be sub-collections.

Still I guess the major point is the data pulled. If you call the user you will directly be pulling out that MB of data. Instead with a sub-collection it won't load, even if you loaded it you can still lazy-load.

I guess for the kind of setup you are doing sub-collections.

like image 26
Victor Abrate Avatar answered Oct 02 '22 15:10

Victor Abrate