0

I am working on a quiz game, where players have to answer questions of different categories (sports, music, .....). Right now, I have two different ideas how to store these categories /questions in Firestore:

  1. Creating a new Root-level collection for each category. Every document in this collection would define a question of that category. Stcuture would look like this:
    • user_collection
      • user_1_document
      • user_2_document
      • user_X_document
    • music_questions_collection
      • music_questions_1_document
      • music_questions_2_document
      • music_questions_X_document
    • sports_questions_collection
      • sports_questions_1_document
      • sports_questions_2_document
      • sports_questions_X_document
  2. Creating ONE Root-level collection and create a document inside this collection for each category, where each document contains a subcollection of questions:
  • user_collection
    • user_1_document
    • user_2_document
    • user_X_document
  • category_collection
    • music_document
      • music_question_subcollection
        • music_question_document_1
        • music_question_document_2
        • music_question_document_3
    • sports_document
      • sports_question_subcollection
        • sports_question_document_1
        • sports_question_document_2
        • sports_question_document_3

I have already read about some advantages and limitations of subcollections and root-collections, but have not found enough information regarding read-costs and speed for this specific use case. Can anyone give me some information about drawbacks and advantages of the two listed approaches.

Renaud Tarnec
  • 79,263
  • 10
  • 95
  • 121
Clyon97
  • 47
  • 6
  • There is a third option. Create one collection for all quiz questions and make fields like `questionLevel` `category` `questionNumber`. And just query them by fields: `query(collection(db, 'quizes'), where('category', '==', 'Sport'), where('quizLevel', '>=', '5'))` – Mises Jul 24 '22 at 07:32
  • @Mises the problem I have with this approach is, that you first have to retrieve ALL questions from a specfic category (where('category', '==', 'Sport') and then retrieve a single question, which is not really cost efficient, because the category collection will contain a lot of documents(questions). – Clyon97 Jul 24 '22 at 08:21
  • In my opinion, you are not cost-efficient. Read about persistence. You can always download once documents and read them from browser cache. And if you make a separate collection for each category, you still have to query them all! – Mises Jul 24 '22 at 08:28
  • Oh, and you are not able in Firestore to get more than 100 documents at once. And to get the certain number of documents you're using `limit(5)` function in query, and you're getting just 5 documents. Read about how to make paginated requests to Firestore. – Mises Jul 24 '22 at 08:34
  • @Mises So let's say I have a collection called "Sports" with 10 000 documents in it. I also put an ID on these documents (1 ... 10 000). In my cloud functions, I would just create a random number between 1 and 10 000, and then query over sports collection with the condition: where('ID', '==', random_Number), which will result in only one document read. – Clyon97 Jul 24 '22 at 08:38
  • @Mises okay you are right, limit(x) would do the job and prevent read inefficiency – Clyon97 Jul 24 '22 at 08:39
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/246708/discussion-between-mises-and-clyon97). – Mises Jul 24 '22 at 08:44
  • 1
    @Mises You mention that "you are not able in Firestore to get more than 100 documents at once". AFAIK there is not such a limit. Can you point out the reference for this limit? – Renaud Tarnec Jul 24 '22 at 09:16
  • @RenaudTarnec Good to know. I don't have a clue why I was sure there is a limit to 100 documents. There is just maximum API request size 10 MiB, and it is about writes not reads. – Mises Jul 24 '22 at 09:55

1 Answers1

2

I have not found enough information regarding read-costs and speed for this specific use case. Can anyone give me some information about the drawbacks and advantages of the two listed approaches?

In terms of "read-costs and speed", the two approaches are equivalent: using a root collection or a sub-collection is exactly the same.

As a matter of fact, from a technical perspective, a root collection and one of its sub-collections are not at all related to each other. They just share a part of their path but nothing else.

So, since you store the same documents in either a root collection or a sub-collection (i.e. same number of docs in each category collection and same field structure for these docs), there is no difference.

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
Renaud Tarnec
  • 79,263
  • 10
  • 95
  • 121