Как я могу объединить два запроса Firestore, используя rxfire и rxjs (запрос OR) - PullRequest
0 голосов
/ 16 ноября 2018

Цель проста: объединить два запроса Firestore с использованием rxjs, rxfire и собственной библиотеки реагирования rnfirebase.

Я прочитал несколько учебных пособий 1 , 2 при присоединении к запросам, но все они терпят неудачу с разными ошибками.

//Simple test for collectionData
import { collectionData } from 'rxfire/firestore';

this.myQuery = this.props.docRef.collection(`messages`).where('read', 'array-contains', this.props.me.uid)
collectionData(this.myQuery, 'id').subscribe(docs => console.log(docs))
//Fails with error: this._next is not a function.

В качестве альтернативы,

this.publicQuery = this.props.docRef.collection('messages').where('public', '==', true) 
this.myQuery = this.props.docRef.collection(`messages`).where('read', 'array-contains', this.props.me.uid)
const myQuery$ = new Rx.Subject();
const publicQuery$ = new Rx.Subject();
this.myQuery.onSnapshot((querySnapshot) => {
    myQuery$.next(querySnapshot.docs.map(d => d.data()  ));
});
this.publicQuery.onSnapshot((querySnapshot) => {
    publicQuery$.next(querySnapshot.docs.map(d => d.data()  ));
});
const orQuery$ = combineLatest(this.myQuery, this.publicQuery).switchMap((docs) => {
    var [one, two] = docs;
    var combined = one.concat(two);
    return Rx.Observable.of(combined);
})
orQuery$.subscribe((result) => {
    console.log('>>>> ', result)
})
//TypeError: undefined is not a function (near ...switchMap)

Как можно успешно объединить два запроса Firestore (ИЛИ)

1 Ответ

0 голосов
/ 27 ноября 2018

Вы уже очень близки к решению.Давайте пошагово рассмотрим проблемы.

Во-первых, нет необходимости создавать Subject только для преобразования вашего результата из onSnapshot.Вместо этого:

this.myQuery.onSnapshot((querySnapshot) => {
    myQuery$.next(querySnapshot.docs.map(d => d.data()))
});

Мы можем добиться того же, используя «операторы преобразования по конвейеру»:

const myQuery$ = this.myQuery.onSnapshot.pipe(
    map(querySnapshot => querySnapshot.docs.map(d => d.data()))
);

То же самое относится и к другому запросу:

const publicQuery$ = this.publicQuery.onSnapshot.pipe(
    map(querySnapshot => querySnapshot.docs.map(d => d.data())
);
* 1013Во-вторых, чтобы объединить эти два запроса, combineLatest действительно является правильной функцией создания.

Однако ваша ошибка может быть вызвана тем, что вы используете более новую версию RxJS, которая больше не поддерживает «беглые» операторы (, официально называемые «операторы патчей» ).Они были заменены «работоспособными операторами» начиная с RxJS 6 и далее.Например, myObs$.map(...) стал myObs$.pipe(map(...)).В руководствах, вероятно, используется более старая версия RxJS, где первая все еще возможна.

Кроме того, нет необходимости использовать switchMap, если внутренняя Observable является просто оператором of.В этом случае достаточно использовать оператор map, который будет вести себя одинаково.

При использовании нового синтаксиса RxJS 6+ вместе с map комбинация будет выглядеть следующим образом:

const orQuery$ = combineLatest(myQuery$, publicQuery$).pipe(
    map(([one, two]) => one.concat(two))
)

Остальная часть кода должна быть правильной.

Side Примечание: Имейте в виду, что эквивалент вашего кода в SQL равен UNION (не JOIN).Чтобы программно JOIN, вам нужно было бы объединить каждый объект набора результатов A с каждым объектом набора результатов B и создать объединенный объект для каждой пары.Такая функция для OUTER JOIN без ключа выглядела бы так (помещается в вашу map трубу):

one.map(a => 
   two.map(b => Object.assign({}, a, b)))
.reduce((p, c) => p.concat(c), [])

Если вы хотите иметь UNION без дублирующихся объектов, объедините только эти элементыиз two, у которых нет соответствующего первичного ключа в списке one.Это будет ваша функция отображения:

one.concat(two.filter(twoItem => !one.some(oneItem => oneItem.id == twoItem.id)))

DEMO: Полная рабочая демонстрация с указанным кодом и смоделированным FireStore может быть найдена здесь:

https://stackblitz.com/edit/rxjs-mefynu?devtoolsheight=60

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...