使用Ngrx在Cloud Firestore中进行大查询

时间:2019-05-11 21:32:02

标签: angular typescript google-cloud-firestore bigdata ngrx

我有一个应用程序,实际上我将至少有5k条记录被多个用户访问。

我正在使用Ngrx通过Cloud Firestore数据库管理应用程序状态。

我使用Angular Material的Table组件,并根据下面的代码进行过滤,我希望获得尽可能最好的记录,并且也希望尽快过滤。

我使用entityAdapter创建实体对象,并使用其数据获取记录,我可以创建一个选择器并通过Id在实体内进行搜索。

但是我该如何尽快过滤MatTableDataSource中加载的数据?

另一个问题是我无法按名称过滤数据。

此刻,我执行下面的表格,但由于有很多记录,因此我不知道这是否是进行搜索的最佳方法。

当我有成千上万的记录时,如何使您表现出色?

database.service.ts

public query(collectionRef: string, collectionType: string) {
    return this._angularFirestore
        .collection(collectionRef)
        .stateChanges().pipe(
            mergeMap(actions => actions),
            map(action => {
                return {
                    type: `${collectionType} ${action.type}`,
                    payload: {
                        ...action.payload.doc.data(),
                        id: action.payload.doc.id,
                    }
                }
            })
        );
}

customers.effects.ts

@Effect()
queryCustomers$ = this._actions$.pipe(
    ofType(customersActions.QUERY),
    switchMap(() => this._store.select(authSelectors.getFirestoreCollection)
        .pipe(first())),
        exhaustMap(firestoreCollection => {
        const collectionRef = `${firestoreCollection}/${this.pathRef}`;
        return this._db.query(collectionRef, this.collectionType);
    })
);

customers-list.ts

    public displayedColumns = ['additionalData.name'];

    public customers: MatTableDataSource<any>;

    this._store.dispatch(new customersActions.Query());

    this._store.select(customersSelectors.selectAll)
        .pipe(takeUntil(this._unsubscribeAll))
        .subscribe((customers) => {
            if (pacientes.length > 10) {
                this.loadingData = false;
            }
            this.customers = new MatTableDataSource(customers);
            this.customers.sort = this.sort;
            this.customers.paginator = this.paginator;
        });

public clearSearch(): void {
    this.searchKey = '';
    this.applyFilter();
}

public applyFilter(): void {
     // Here you are not filtering the name, only filtering the name if it 
     // is not within additional data.
    this.customers.filter = this.searchKey.trim().toLowerCase();
}

customers-list.html

        <!-- SEARCH -->
        <div class="search-wrapper mx-32 mx-md-0">
            <div class="search" fxFlex fxLayout="row" fxLayoutAlign="space-between center">
                <mat-icon>search</mat-icon>
                <input [(ngModel)]="searchKey" matInput placeholder="Search customers" autocomplete="off"
                    (keyup)="applyFilter()">
                <button *ngIf="searchKey" mat-icon-button (click)="clearSearch()">
                    <mat-icon>close</mat-icon>
                </button>
            </div>
        </div>
        <!-- / SEARCH -->

            <ng-container matColumnDef="additionalData.name">
                <mat-header-cell *matHeaderCellDef mat-sort-header>Name</mat-header-cell>
                <mat-cell *matCellDef="let customer">
                    <p class="text-truncate font-weight-600">{{customer.additionalData.name}}</p>
                </mat-cell>
            </ng-container>

0 个答案:

没有答案