Are there any benefits of using subcollections in firestore?

前端 未结 2 614
旧时难觅i
旧时难觅i 2020-12-29 04:53

I have a subcollection for each doc in the users collection of my app. This subcollection stores docs that are related to the user, however they could just as well be saved

相关标签:
2条回答
  • 2020-12-29 05:42

    Let's take an example for that. Let's assume we have a database schema for a quiz app that looks like this:

    Firestore-root
        |
        --- questions (collections)
              |
              --- questionId (document)
                     |
                     --- questionId: "LongQuestionIdOne"
                     |
                     --- title: "Question Title"
                     |
                     --- tags (collections)
                          |
                          --- tagIdOne (document)
                          |     |
                          |     --- tagId: "yR8iLzdBdylFkSzg1k4K"
                          |     |
                          |     --- tagName: "History"
                          |     |
                          |     --- //Other tag properties
                          |
                          --- tagIdTwo (document)
                                |
                                --- tagId: "tUjKPoq2dylFkSzg9cFg"
                                |
                                --- tagName: "Geography"
                                |
                                --- //Other tag properties
    

    In which tags is a subcollection within questionId object. Let's create now the tags collection as a top-level collection like this:

    Firestore-root
        |
        --- questions (collections)
        |     |
        |     --- questionId (document)
        |            |
        |            --- questionId: "LongQuestionIdOne"
        |            |
        |            --- title: "Question Title"
        |
        --- tags (collections)
              |
              --- tagIdOne (document)
              |     |
              |     --- tagId: "yR8iLzdBdylFkSzg1k4K"
              |     |
              |     --- tagName: "History"
              |     |
              |     --- questionId: "LongQuestionIdOne"
              |     |
              |     --- //Other tag properties
              |
              --- tagIdTwo (document)
                    |
                    --- tagId: "tUjKPoq2dylFkSzg9cFg"
                    |
                    --- tagName: "Geography"
                    |
                    --- questionId: "LongQuestionIdTwo"
                    |
                    --- //Other tag properties
    

    The differences between this two approaches are:

    • If you want to query the database to get all tags of a particular question, using the first schema it's very easy because only a CollectionReference is needed (questions -> questionId -> tags). To achieve the same thing using the second schema, instead of a CollectionReference, a Query is needed, which means that you need to query the entire tags collection to get only the tags that correspond to a single question.
    • Using the first schema everything is more organised. Beside that, in Firestore Maximum depth of subcollections: 100. So you can take advantage of that.
    • As also @RenaudTarnec mentioned in his comment, queries in Cloud Firestore are shallow, they only get documents from the collection that the query is run against. There is no way to get documents from a top-level collection and other collections or subcollections in a single query. Firestore doesn't support queries across different collections in one go. A single query may only use properties of documents in a single collection. So there is no way you can get all the tags of all the questions using the first schema.

    This technique is called database flatten and is a quite common practice when it comes to Firebase. So use this technique only if is needed. So in your case, if you only need to display the tags of a single question, use the first schema. If you want somehow to display all the tags of all questions, the second schema is recommended.

    Is it solely there so that you can expand if your doc becomes close to the 1MB limit?

    If you have a subcollection of objects within a document, please note that size of the subcollection it does not count in that 1 MiB limit. Only the data that is stored in the properties of the document is counted.

    Edit Oct 01 2019:

    According to @ShahoodulHassan comment:

    So there is no way you can get all the tags of all the questions using the first schema?

    Actually now there is, we can get all tags of all questions with the use of Firestore collection group query. One thing to note is that all the subcolletions must have the same name, for instance tags.

    0 讨论(0)
  • 2020-12-29 05:46

    The only potential technical advantage to sub-collections that I can think of relates to document size -- it allows you to omit a reference to the parent element. (i.e. for each related rootDocument -> subCollection, there is a single pointer from the root collection document to the subcollection).

    Subcollection

    /messages
    |
     --> /messages/tags
    

    When tags are a sub-collection then they don't need to save the messageId because you access the tags through message document:

    collection("messages").document(messageId).collection("tags")
    

    Root collection

    /messages
    /tags
    

    With a root tags collection each tag would need to store messageId. This basically flips the direction of the pointers.

    collection("tags").whereEqualTo("messageId", messageId)
    

    Summary

    Sub-collection: pointers go from one -> many

    Root collection: pointers go from many -> one

    0 讨论(0)
提交回复
热议问题