Reputation: 73
I am working on an iOS app. For it I have a firebase database containing ingredients and recipes. It is not hard to imagine; a recipe has child ingredients associated with it, and an ingredient can be included in multiple recipes. An example of my JSON structure is below:
{
"ingredients" : {
"chicken" : {
"meal1" : true,
"meal2" : true
},
"beef" : {
"meal2" : true
},
"lamb" : {
"meal1" : true,
"meal3" : true
}
},
"meals" : {
"meal1" : {
"ingredients" : {
"chicken" : true,
"lamb" : true
}
},
"meal2" : {
"ingredients" : {
"chicken" : true,
"beef" : true
},
"meal3" : {
"ingredients" : {
"lamb" : true
}
}
}
The question: what is best practice for querying for a list of recipes that contain a set of ingredients selected by a user and adding them to an array of recipe objects without pulling in duplicate recipes? I am looking for all recipes which include at least 1 ingredient match.
Example: a user is searching for recipes including "chicken" and "beef" from my example db, I expect to return recipe1 and recipe2. Recipe2 includes both chicken and beef so I would not want it to be pulled into search results twice.
My first thought was to query for all meals under first chicken and then query for all meals under beef and then do some kind of function to remove duplicates. This seems to me not to be a good solution because you could generate multiple duplicate meals that you would have to remove in theory. Is there a better way?
Upvotes: 1
Views: 740
Reputation: 4858
Firebase itself does not offer you a way to use multiple queries or chains. That prevents you from slowing down your application too much. (we should be happy about it).
Now there are three different ways to still get the desired result.
frontend queries:
If you don't expect to have tons of data this is probably the easiest way to achieve your goal. Don't be shy to use them, they can be pretty efficient.
data structure:
The second approach would it be to restructure your database. Believe me, you can achieve every imaginable query chain
on this way.
Combine both of this methods. Sometimes you can build a structure to reduce the number of returned values and then use frontend queries to make the rest.
In your case, you already have a very nice structure. So let's say the user is searching for lamb
and chicken
you could just call those nodes and do some kind of merge in the frontend.
But yeah it could be faster. Probably the best approach would it be to mirror your data. You could create nodes like chicken-lamb
, chicken
, lamb
and then call them directly. Of course, this can end up in a lot of data, but it's extremely fast.
Let's say the user searches for chicken
, beef
and lamb
. You would simply create an alphanumeric order to get the node: /beef-chicken-lamb
.
Following this approach, you can avoid any queries. So if you are really into performance this is an awesome way to do.
Upvotes: 3