This question already has answers here:
Firebase Query Double Nested
(3 answers)
Closed 4 years ago.
I have the following data structure:
items:
id1 - dynamically set, unknown
id2 - dynamically set, known
item: data
I want to get all data inside id2.
Using firebase.database().ref('items').orderByChild('item').equalTo('data') I get null but at the same time it's no problem to access all data inside id1 though. Apparently using this method it's impossible to access data with 2 and more levels of depth.
Firebase declares they support up to 32 levels of nesting. So there should be some methods for advanced searching data anyways.
How can one access an object with known property and known value while searching at 2 or more levels of depth with arbitrary keys?
Unfortunately firebase realtime database gives you the ability to filter children only one level deep. If you have the flexibility to reach the specific id1(which you declared unknown), you can filter with orderByChild and equalTo method for item by going down the hierarchy. Alternatively you can filter manually client side or change your data structure if you have the chance.
From the firebase reference:
Filter by key or value
You can use startAt(), endAt(), and equalTo()
to choose arbitrary starting, ending, and equivalence points for
queries. This can be useful for paginating data or finding items with
children that have a specific value.
https://firebase.google.com/docs/database/web/lists-of-data
Related
I am working on a Flutter project where I need to display the list of government agencies. I should implement two levels of filters. 1. State to which the agency belongs and 2. Service provided by the agency. So I have some choice chips to select the agent based on service and a checkbox-based dropdown for filtering states. As a result, I need to apply logical or based filters on state and service fields. Since that's impossible I thought of adding a helper field that holds both data in an array format. so that I could work on a single field with array-contains-any filter.
Now there is one more problem, let's say there are twelve states and 5 services, and I am selecting 6 states and 3 services. I need to create a total of 18 arrays which is also not supported by Firestore as the maximum is 10.
Please share with me an idea of any approach I could take;
Don't use arrays, simply use maps. There are no limitations regarding how many where equal methods are you chaining. The key of the Map will be the name of an agency and the value will be the boolean true. And you can add as many maps as you want.
This question already has an answer here:
firebase equivalent to sql where in ()
(1 answer)
Closed 5 years ago.
I use orderByKey for requesting data by keys from Firebase. I can get several objects if keys are similar — start or end with the same string.
But how can I retrieve totally different keys with one request to Firebase, e.g. "n:1-2-3" and "n:2-3-4"? I use equalTo, but can I specify more than one key there?
I know how to do it with different requests — one request per one key, but it's not optimal.
Currently firebase only supports one condition. Explained more in the below text:-
If lets say you have two keys that are a123 and a234 then to retrieve you can do this:
DatabaseReference ref=FirebaseDatabase.getInstance().getReference();
ref.orderByKey().startAt("a").limitToLast(10).addValueEventListener(..){..}
The limitToLast() method is used to set a maximum number of children to be synced for a given callback
You can use limittolast or limittofirst, to limit the results that are obtained from the database.
Also currently firebase only supports one condition. So you cannot have more than one orderbykey or orderbychild or the two together..
I am starting to use Firebase to store data information. I learned that it is better to have it in a narrow structure instead of deep structure.
I have the following structure:
MainDetail
-Kd92jd93kaod93 <----ID
-Kfirkd9rmtiepr
-.....More than 1 million more
The question I have is that, I have over a million data and over a million ID's will be stored in a linear sequence under each main nodes like above.
Is this a good approach to have all the ids in one nodes? or should I break it down further such as by a date? Like...
01_MainDetail
-20170902
-Kd92jd93kaod93
-Kfirkd9rmtiepr
-....
-20170901
-Kd92jd93rt4e3
-Kfer5hrmtiepr
-....
-....
This contradicts what I read online as now I am not making it narrow and having multiple children.
What is the right approach when I have lots of data?
There is no realistic limit on the number of child nodes under a node. It all depends on how you want to access those child nodes. Specifically:
Querying long lists of data will always take more time than querying a shorter list of data.
Reading a list of nodes will always be faster that querying for those same nodes from a longer list.
See these answers for more:
How many records / rows / nodes is alot in firebase?
Firebase Performance: How many children per node?
Does Firebase limitToLast() take increasing longer as a child's record count grows?
It is often best to partition data to match with how you want to access it. The second data structure you show is an example of that, since it allows you to access the nodes for a specific date without needing to query for them.
The Good approach is to keep data organised like you said in chunks of dates under parent node.
This approach will not be a source of trouble for you.
The data model I am planning would have a few property "fields" in place, including a "category/tags" property, which would be a list/array of a lot of tags.
I'm planning on querying on one category at a time. I am not interested in indexing which entities have combinations of categories, just individual categories.
I am NOT referencing simply not indexing a particular property.
Bonus Question:
It seems Google datastore doesn't like "monotonically increasing" property values (ie timestamps) because presumably they make hotspots on the machines while forming indexes. So would just storing the current calendar date help? I could see that making even more of a "hotspot" since every entity for 24 hours would have the same index value for that property, is there some way of storing some data about when each entity was recorded?
Indeed, one should encounter no issues creating a builtin index, as mentioned in the above reply. Still, properties with array values can behave in surprising ways. For more than one filter, all conditions defined by the filters must be satisfied by at least one of the array’s individual values, for it to match the query. This does not apply in case of the equality filters.
Sort order is also unusual: the first value seen in the index determines an entity's sort order.
I don't think a property index (aka Built-in Index) on an Array property creates the index with various value combinations. I believe each value in the Array is indexed. For example, if you have a Book with two tags, the index will have two entries for each tag. Adding another book with three tags would add 3 more entries to the Tags index. This index allows you to query for books based on a single tag as well as multiple tags.
The "combination of values" that you mentioned happens if you create a composite index containing more than one Array type (e.g. Authors and Tags of a Book), and all/most books have multiple authors and multiple tags.
You should not have any issues creating a builtin index on your Category/Tag.
On your other question on indexing entity created/modified timestamp, I do see that the Best Practices says to avoid indexing such a property.
Do not index properties with monotonically increasing values (such as
a NOW() timestamp). Maintaining such an index could lead to hotspots
that impact Cloud Datastore latency for applications with high read
and write rates
Not sure what the alternative would be. If you don't have to query on the timestamp/sort on the timestamp, you are fine storing the timestamp by excluding the property from indexing.
I have read the Firebase docs about priorities but I don't think I understand it yet.
I think I understand that it is related to querying and sorting data. To give my question (and the answers) some weight, in what instances might you use priorities?
From the docs I read that you can set priorities when you set a value at some reference, and then when you query that reference priority determines the ordering based on its type and value. And that makes some sense but I'm not quite understanding it.
Disclosure: I work for Firebase.
Priorities are an optional (numeric or alphanumeric) value of each node, which is used to sort the children under a specific parent or in a query if no other sort condition is specified. The priority of a node is hidden from most views of the data. In cases where a priority is specified for a node, it can be found as a .priority property in the exportVal() of a snapshot.
Since Firebase added the ability to order children on a specified property, priorities have lost most of their value. They are a left-over artifact from the time before Firebase had orderByChild queries. If you are starting on a Firebase project today, you should use orderByChild instead of relying on priorities.