This is possible with the firestore?
Yes it is.
We need to find recipes that contain at least one of the ingredients. How to implement it?
In order to implement this feature, you should use arrays. Please see below a database schema, that can help you achieve this:
Firestore-root
|
--- recipes (collection)
|
--- recipeId (document)
|
--- ingredients: ["salt", "pepper"] (array)
|
--- //other decipe details
In order to find all recipes that contain one of the ingredients, you should use a query that looks like this:
FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
Query query = rootRef.collection("recipes").whereArrayContains("ingredients", "salt");
This is for Android but in the same way you can achieve this for other programming languages. See here more details.
But be aware of one thing, you cannot find all recipes that contain more than one of the ingredients, without making significant changes in your database. Firestore does not allow chained whereArrayContains()
calls. So you can get all recipes that contain only one of the ingredients.
Edit: According to your comment:
How to choose a recipe in which there is either "pepper" OR "salt"?
You need to know that there is no OR
clause in Firestore. According to my answer from this post, you should create two separate queries and merge the result cliend side.
Edit2:
100,000 recipes to combine on the client.
If this is the use-case of your app then you should query this way. Firestore scales massively.
But this is a fairly simple query!
It is in terms of SQL databases but this is how NoSQL databases work.
If you need to exclude recipes with the ingredient "sugar"?
According to the official documentation, beside the fact that there is no OR
clause, there is also another query limitation:
Queries with a != clause. In this case, you should split the query into a greater-than query and a less-than query.
So this is the way in which you can solve this exclude
or not equal
situation.
Your link also does not solve the problem.
My link cannot solve a problem that cannot be solved in the way you want, it just indicates the constraints that Firestore official documentation provides. In that link, I also provide a workaround in the way the docs recommend. In this case, you should make your own attempt given the information in my answer and that post and ask another question if something else comes up.
The result - recipes with salt AND pepper. But not salt OR pepper!
No, if you create two separate queries and merge the result cliend side, you'll have the desired result. I've test it and it works pretty fine.
I know that there is no "OR". I therefore ask - is there a solution?
Yes it is, the solution I have provided you above, which is the simplest one. If you are not happy with that, you might also consider change your entire database structure so it can be organized according to a reverse look up. Your structure should look like this:
Firestore-root
|
--- salt_peper (collection)
| |
| --- recipeId (document)
| | |
| | --- //recipe with salt
| |
| --- recipeId (document)
| |
| --- //recipe with peper
|
--- salt_sugar (collection)
|
--- recipeId (document)
|
--- //recipe details
As you can see, this is another schema for your database. The first collection will provide you all recipes with salt OR
peper.
This practice is called denormalization
and is a common practice when it comes to Firebase. For a better understanding, I recommend you see this video, Denormalization is normal with the Firebase Database. It is for Firebase realtime database but same principle apply to Cloud Firestore.
Also, when you are duplicating data, there is one thing that need to keep in mind. In the same way you are adding data, you need to maintain it. With other words, if you want to update/detele an item, you need to do it in every place that it exists.
I also recommend you take a look at my answer from this post to see pro and cons regarding the tehnique above.