Я создаю приложение StencilJS
(без фреймворка) с бэкэндом Google Firestore и хочу максимально использовать библиотеки RxFire
и RxJS
для упрощения кода доступа к данным. Как я могу объединить в один наблюдаемый поток данных, поступающих из двух разных коллекций, которые используют ссылочный идентификатор?
В Интернете есть несколько примеров, которые я прочитал и попробовал, каждый из которых использует различную комбинацию операторов с разным уровнем вложенности. https://www.learnrxjs.io/ кажется хорошим ресурсом, но он не дает примеров для бизнеса, которые имеют смысл для меня. Этот вопрос очень похож, и, возможно, единственное отличие - это какой-то перевод в использование RxFire? Все еще смотрю на это. Просто для сравнения, в SQL это будет оператор SELECT
с INNER JOIN
на ссылочном идентификаторе.
В частности, у меня есть коллекция для Games
:
{ id: "abc000001", name: "Billiards" },
{ id: "abc000002", name: "Croquet" },
...
и коллекция для Game Sessions
:
{ id: "xyz000001", userId: "usr000001", gameId: "abc000001", duration: 30 },
{ id: "xyz000002", userId: "usr000001", gameId: "abc000001", duration: 45 },
{ id: "xyz000003", userId: "usr000001", gameId: "abc000002", duration: 55 },
...
И я хочу наблюдать объединенную коллекцию Game Sessions
, где gameId
по существу заменяется на Game.name
.
В настоящее время у меня есть game-sessions-service.ts
с функцией для получения сеансов для определенного пользователя:
import { collectionData } from 'rxfire/firestore';
import { Observable } from 'rxjs';
import { GameSession } from '../interfaces';
observeUserGameSesssions(userId: string): Observable<GameSession[]> {
let collectionRef = this.db.collection('game-sessions');
let query = collectionRef.where('userId', '==', userId);
return collectionData(query, 'id);
}
И я пробовал разные варианты с pipe
и mergeMap
, но я не понимаю, как сделать так, чтобы они все правильно совмещались. Я хотел бы установить интерфейс GameSessionView
для представления объединенных данных:
export interface GameSessionView {
id: string,
userId: string,
gameName: string,
duration: number
}
observeUserGameSessionViews(userId: string): Observable<GameSessionView> {
this.observeUserGameSessions(userId)
.pipe(
mergeMap(sessions => {
// What do I do here? Iterate over sessions
// and embed other observables for each document?
}
)
}
Возможно, я просто застрял в нормальном мышлении, поэтому я открыт для предложений о лучших способах управления данными. Я просто не хочу слишком много дублирования для синхронизации.