Reputation: 135
I am building an app using Firebase and am having trouble structuring the data for a hierarchy that my app needs.
Concept
My app consists of items
. Each item can have n
-many child items
. There will be 100s of thousands of items in the database and for any given item. I want to get a count of all child items (i.e.: direct children, grand children, great grandchildren, etc).
Current structure example
items: {
1: {
name: 'neat item 1'
},
2: {
name: 'neat item 2',
parentId: 1
},
3: {
name: 'neat item 3',
parentId: 2
}
}
Question
In Firebase, what is the best way to track the number of children an item has? So in the example above, item #1 has a total 2 children, item #2 has a total of 1 child.
Would it be best to maintain a childCount
on each item and whenever a new item is added, increment that number for all parents? Or would it be better to recursively compute the child count whenever it's needed?
Keeping in mind that there will be 500,000+ items in the database, with some items having a total of 10,000+ children.
Thanks so much for your time!
Upvotes: 3
Views: 2183
Reputation: 598887
In Firebase (as in most NoSQL databases) you should model the data for the way your app uses it (I highly recommend reading this article on NoSQL data modeling for more pieces of wisdom).
An important thing to realize is that Firebase always loads the entire node, including all data under that node. There's no way (within the SDKs) to load so-called shallow data.
So if your app always shows the entire tree, than you can definitely model the data as a tree.
But given the size of the tree, it is much more likely that you're going to show one level at a time and then allow the user to click to expand that level. If you'd model the data as a hierarchy, you'd end up loading all children of a node, even when the user never expands that node. That is wasteful.
So more common is to store the hierarchy as a list, pretty similar to how you'd store it in a relational database. You'd then keep a separate list of children of each node. Note that this is a list, not a tree.
nodes
nodeKey1
name: "Node 1"
childrenCount: 2
nodeKey2
name: "Node 2"
childrenCount: 1
parentKey: "nodeKey1"
nodeKey3
name: "Node 3"
childrenCount: 0
parentKey: "nodeKey1"
nodeKey4
name: "Node 4"
childrenCount: 0
parentKey: "nodeKey2"
nodeChildren
nodeKey1
nodeKey2
nodeKey3
nodeKey2
nodeKey4
This allows for efficient reading/querying of:
ref.orderByChild('parentNode').equalTo(null)
)If you have more use-cases, you may need to expand the data model.
Upvotes: 2