Как запрашивать и объединять несколько коллекций в Firebase - PullRequest
0 голосов
/ 07 октября 2019

Мне нужно получить ежемесячную коллекцию рабочих заданий по проектам и списку пользователей (в этом месяце у меня могут быть часы OdL некоторых проектов, не включенные в список пользователей, и пользователи могут иметь некоторые OdL других проектов). Модель OdL содержит строки для проекта (projectCode) и пользователя (userId). Я отправляю в сервис даты в формате Timestamp, код проекта и массив со списком пользователей.

this.loadGantt(from: Timestamp, to: Timestamp, projectCode: string, users: string[]){...}

Я пытался выполнить отдельные запросы, один для кода проекта и один для одного пользователя. Это запросы службы:

this.docs = this.afs.collection<OdlModel>('odl', ref => {
      return ref.where('projectCode', '==', project)
        .where('date', '>=', from)
        .where('date', '<=', to)
        .orderBy('date', 'asc');
    })
      .snapshotChanges().pipe(map(coll => {
        return coll.map(doc => ({ id: doc.payload.doc.id, ...doc.payload.doc.data()}));
      }));
    return this.docs;

this.docs = this.afs.collection<OdlModel>('odl', ref => {
      return ref.where('userId', '==', user)
        .where('date', '>=', from)
        .where('date', '<=', to)
        .orderBy('date', 'asc');
    })
      .snapshotChanges().pipe(map(coll => {
        return coll.map(doc => ({ id: doc.payload.doc.id, ...doc.payload.doc.data()}));
      }));
    return this.docs;

Это решение, которое я нашел:

loadGantt() {
    const momentDate: Moment = moment(new Date());
    this.firstDay = momentDate.startOf('month').toDate();
    this.lastDay = momentDate.endOf('month').toDate();
    const from = firebase.firestore.Timestamp.fromDate(this.firstDay);
    const to = firebase.firestore.Timestamp.fromDate(this.lastDay);
    this.odl = [];
    const odlArray = [];
    const a$ = this.odlService.getProjectOdlCollection(from, to, 'IGNC0954-IMI-19');
    odlArray.push(a$);
    this.user.forEach(u => {
      const b$ =  this.odlService.getUserOdlCollection(from, to, u);
      odlArray.push(b$);
    });
    const result$ = combineLatest([odlArray]);

    result$.subscribe(res => {
      res.map(r => {
         r.subscribe(odl => {
           odl.forEach(o => {
             const index = this.odl.findIndex(x => x.id === o.id);
             if (index === -1) {
               this.odl.push(o);
             }
           });
         });
      });
    });
  }

Как получить все данные в одном объекте Observable?

1 Ответ

0 голосов
/ 16 октября 2019

Ниже приведен фрагмент, который показывает, как объединить две или более коллекции Firestore из AngularFire в один объект Observable.

Ссылка здесь

Структура данных

const usersRef = this.afs.collection('users');

const fooPosts = usersRef.doc('userFoo').collection('posts').valueChanges();
const barPosts = usersRef.doc('userBar').collection('posts').valueChanges();

Решение

import { combineLatest } from 'rxjs/observable/combineLatest';


const combinedList = combineLatest<any[]>(fooPosts, barPosts).pipe(
      map(arr => arr.reduce((acc, cur) => acc.concat(cur) ) ),
      )

Также этот пример также может помочь с вашей проблемой.

Дайте мне знать, если это было полезно.

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