I have a simple app with Firebase database (Realtime Database).
I know that I am using a non relational database. Not the best for complex queries.
1. For example, if I want to find the recipes with
time:15 && name: "rice and eggs"... Is it possible?
I know that I can find the recipes with (time=15)
DatabaseReference ref = databaseReference.child("recipes");
Query filtro = ref.orderByChild("time").equalTo(15);
Is there a way to find recipe with
time:15 && name: rice and eggs... ?????? (multiple querie)
2. Another issue, I am saving ingredients in an arrayList.
arrayListIngredient = new ArrayList<Ingredient>();
int i = 0;
while (i < size){
Ingredient ingredient = new Ingredient(ingredientName[i]);
arrayListIngredient.add(ingredient);
i ;
}
Recipe recipe = new Recipe();
recipe.setTime(time);
recipe.setName(name);
recipe.setNameIngredient(arrayListIngredient);
DatabaseReference reference = databaseReference.child("recipe").push().setValue(recipe);
Is there a way (query) to search recipes with specific ingredients if I store my data like this???
For example, I want to know the recipes whose ingredients are rice, tomato, onion.
CodePudding user response:
The simple answer is: no, this type of query isn't possible on Firebase. If you need this type of expressive query and want ad-hoc querying on your database, consider using a SQL database - those are much better suited for dynamic and ad-hoc queries.
To the specifics of your question:
- Firebase Database queries can only order/filter on a single property. In many cases it is possible to combine the values you want to filter on into a single (synthetic) property. For an example of this and other approaches, see my answer here: Query based on multiple where clauses in Firebase
- What you're showing in your screenshot is a set-like structure that you store as an array. That is not ideal for querying, and you should consider storing it as a map. For more on this, see my answer here: Firebase query if child of child contains a value
But even with those cases covered, I don't think what you want to accomplish is possible on Firebase Realtime Database without extensive data duplication and client-side processing. Hence my recommendation to consider using a SQL database.
CodePudding user response:
Honestly, the Realtime Database will be more of a headache in this use case if you wish to handle complex filtering at the database level. You could filter based on one aspect and then perform additional filters client-side to suit your UI.
If you wish to continue with Firebase, I would highly recommend Firestore instead. Your data structure would not have to change at all and you would be able to perform complex queries as you wish. The semantics are a bit different, but this is the equivalent query using Firestore:
import { collection, query, where } from "firebase/firestore";
import db from "./where/your/firebase/config/lives.js";
const recipesDatabase = collection(db, "cities");
const recipesByIngredient = query(recipesDatabase, where("time", "==", 15), where("ingredients", "array-contains", ["rice", "tomato", "onion"]));
The "array-contains" operator will find recipes using all of the listed ingredients. Alternatively, you can use "array-contains-any" which will query all recipes containing any of the searched ingredients. See Firestore docs regarding indexes to help facilitate this.