I am looking for a more optimal way to implement the following method getting all my documents from my permits collection, than mapping company and process area data into my permit data used in a PrimeNG table.
Performance > Firebase document reads usage.
Here is my getAllPermits$()
method so far:
getAllPermits$() {
return combineLatest([
collectionData(this.permitCollection) as Observable<any[]>, //will query this later to only show active permits
collectionData(this.companyCollection, {idField: 'uid'}) as Observable<Company[]>,
collectionData(this.processAreasCollection, {idField: 'uid'}) as Observable<ProcessArea[]>,
]).pipe(
map(([permits, companies, processAreas]) => {
return permits.map(permit => {
if (permit.companyUid) {
const company = companies.find(c => c.uid === permit.companyUid);
if (company) {
permit = {...permit, companyName: company?.name ?? 'Error'};
} else {
permit = {...permit, companyName: 'Not Found'};
}
} else {
permit = {...permit, companyName: 'No Company'};
}
if (permit.processArea) {
const processArea = processAreas.find(pa => pa.assetNumber === permit.processArea);
if (processArea) {
permit = {...permit, processAreaName: processArea?.description ?? 'Error'};
} else {
permit = {...permit, processAreaName: 'Not Found'};
}
} else {
permit = {...permit, processAreaName: 'No Process Area'};
}
return permit;
});
})
);
}
Is querying single documents in the companyCollection
and processAreasCollection
more efficient, as opposed to mapping as shown above?
Context:
I would normally have 200 – 500 active permits (this isn’t in the code yet, but this is easy implement later).
companyCollection
= 300+ companies where we might use 100-150 companies in the currently active permits.processAreas
= 160+ areas – again, we might use 50-70 areas in the actively shown permits.
I am using a big portion of the company and process area collection data, hence the question.
2
Answers
faster searches could be done by using
Map
, then instead of.find
which takesO(n)
it would take you onlyO(1)
operations for searchthis way there shouldn’t be a problem with long remapping. But you’ll probably get some freezes during rendering large lists of data.
For the best performance, move away from the relational model that you currently have, and embrace the NoSQL nature of Firestore by duplicating data.
For example, if you duplicate the data that you need from
processAreasCollection
andcompanyCollection
into each document inpermitCollection
, you only need to load the documents from the latter. This may seem very unnatural at first, but it’s actually key to getting great performance out of a NoSQL database like Firestore.If this is new to you, I recommend reading NoSQL data modeling and watching the Get to know Cloud Firestore video series.