Большие запросы в Cloud Firestore с использованием Ngrx - PullRequest
0 голосов
/ 12 мая 2019

У меня есть приложение, в котором у меня будет по крайней мере 5 тыс. Записей, к которым могут обращаться несколько пользователей.

Я использую Ngrx для управления состоянием приложения с помощью базы данных Cloud Firestore.

Iиспользуйте компонент Table Angular Material , и я делаю фильтр в соответствии с приведенным ниже кодом, я хотел бы получить записи как можно лучше, а также фильтровать как можно быстрее.

Iиспользовать entityAdapter для создания объекта entity, для извлечения записи с его данными. Я могу создать селектор и искать в сущностях по 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);
    })
);

клиентов-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();
}

customer-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>
...