Here is my code:
Query query = firestore.collection("users")
.document(myUserID)
.collection("unseen_profiles")
.whereEqualTo("country", myProfileCountryFilter);
if (!myProfileGenderFilter.isEmpty() && !myProfileGenderFilter.equalsIgnoreCase("everyone")) {
query = query.whereEqualTo("gender", myProfileGenderFilter);
}
if (heightFilterOn) {
query = query.whereGreaterThanOrEqualTo("height", minimumHeight);
}
if (weightFilterOn) {
query = query.whereLessThanOrEqualTo("weight", maximumWeight);
}
if (customAgeFilterOn) {
query = query.whereGreaterThanOrEqualTo("age", minimumAge)
.whereLessThanOrEqualTo("age", maximumAge);
}
if (lookingForFilterOn) {
query = query.whereArrayContainsAny("looking_for", lookingForArray);
}
if (personalityTypeFilterOn) {
query = query.whereIn("personality_type", personalityTypeList);
}
if (homeCountryFilterOn) {
query = query.whereEqualTo("home_country", homeCountryFilter);
}
// Add orderBy for timestamp
query = query.orderBy("timestamp");
// Configure the adapter options
PagingConfig config = new PagingConfig(
10, // PageSize
5, // PrefetchDistance
false // EnablePlaceholders
);
FirestorePagingOptions<DataModel> options = new FirestorePagingOptions.Builder<DataModel>()
.setLifecycleOwner(this) // Lifecycle owner
.setQuery(query, config, DataModel.class) // Query and the model class
.build();
Now when different conditions satisfy, every time the app crashes & ask to create an index. But considering combination of the above conditions, if I have to create index for all of them then a huge number of index needs to be created.
I heard that if I need to create many indexes then maybe I am not using query efficiently or maybe I need to optimize the data structure. But in my case I don’t find any other viable options to achieve desired functionality with the query. Am I missing anything? If I am not missing anything then how can I manage creating such large of indexes with time efficiency? Is there any way I can automate creating index when the query requires without the app crashing or query failing?
2
Answers
That’s because all those queries require an index.
Yes, you have to create an index for each combination. So as long as you stay below the maximum limitation which is 200, when you have not enabled billing for your Google Cloud project, then there will be no problems. If you enable billing for your Google Cloud project, then the maximum number is 500. If these 500 indexes are not enough, then you can contact support to request an increase to this limit.
If you need to create many indexes, it doesn’t mean that you’re not using the query efficiently. It simply means that you need to filter the data using many combinations, which is fine given the fact that you have so many fields that you need to filter on.
Yes, you can deploy the Firestore indexes using the Firebase CLI.
While each query needs to be backed by an index (as Alex said), you may not need a separate index for each query. It may be able to use multiple smaller indexes for a single query, by merging their contents. As explained in the documentation on using merged indexes:
I recommend reading the entire documentation section, as it explains in more detail and shows an example.
Queries executed on multiple merged indexes are usually slower than those for which an exact composite index exists though, so you’ll have to trade off performance versus the number of indexes (and their cost).