После еще нескольких испытаний я смог достичь своей цели, даже если результат более чем неоптимальный.
Я отредактировал код, строящий запросы AND / OR, следующим образом:
filterPlaces(queryFilter: FilterModel): Observable<Place[]> {
const queryResults: Observable<Place[]>[] = [];
const typeFilter = queryFilter && queryFilter.typeFilter ? queryFilter.typeFilter : [];
const starsFilter = queryFilter && queryFilter.starsFilter ? queryFilter.starsFilter : [];
// No filter items selected
if (typeFilter.length < 1 && starsFilter.length < 1) {
return this.queryPlaces(null);
}
if (typeFilter.length > 0 && starsFilter.length > 0) {
// Multiple filters internally in OR and among them in AND
starsFilter.forEach(starFilter => {
// FIXME: The number of Calls grows with the filters used!!
typeFilter.forEach(filter => {
queryResults.push(
this.afs
.collection<Place>(this.PLACE_COLLECTION, ref =>
ref
.orderBy('placeName')
.where('type', '==', filter)
.where('rate', '==', starFilter)
)
.valueChanges()
);
});
});
} else {
// Individual OR Cases
if (typeFilter.length > 0) {
typeFilter.forEach(filter => {
queryResults.push(
this.afs.collection<Place>(this.PLACE_COLLECTION, ref => ref.orderBy('placeName').where('type', '==', filter)).valueChanges()
);
});
}
if (starsFilter.length > 0) {
starsFilter.forEach(filter => {
queryResults.push(
this.afs.collection<Place>(this.PLACE_COLLECTION, ref => ref.orderBy('placeName').where('rate', '==', filter)).valueChanges()
);
});
}
}
return combineLatest(...queryResults, (...arrays) => arrays.reduce((acc: any, array: any) => [...acc, ...array], [])).pipe(shareReplay(1));
}
Если пользователь выбирает хотя бы значение в обоих фильтрах, я перебираю выбранные элементы одногофильтровать, и я добавляю их как условие «И» к каждому элементу, выбранному во втором фильтре.
Таким образом, я могу выполнять запросы типа: «Получить (Гостиница И Бар) И (1 * ИЛИ 2 *»ИЛИ 5 *) " например.
Однако этот подход подходит только для небольших фильтров, так как количество вызовов увеличивается с увеличением количества фильтров и их выбранных элементов.Я оставляю этот код здесь, поскольку он может быть источником вдохновения для кого-то другого.Мне любопытно, если кто-нибудь может предложить, как ответить на мой первоначальный вопрос или улучшить текущее решение.