У нас есть коллекция airports
со списком аэропортов, управляемых администратором. Дублирование этого списка есть в каждом наборе клиентов companies/{companyId}/airports
. В каждом документе этой коллекции те же данные только для чтения, что и в «основном» документе, плюс дополнительные данные, индивидуальные для каждого клиента.
Поэтому, если мы обновляем, добавляем или удаляем какой-либо аэропорт в коллекции основных аэропортов, мы также хотим обновить тот же документ в подколлекции аэропортов каждого клиента.
Я создал эту функцию:
import {chunk} from 'lodash';
export const db = admin.firestore();
export const MAX_BATCH_SIZE = 500;
export async function updateCustomersAirports(change: Change<DocumentSnapshot>, context: EventContext) {
const airportId: string = context.params.airportId;
const newAirportData: DocumentData = change.after.exists ? change.after.data() : null;
try {
const companies = await getCompanies();
const batches = chunk(companies, MAX_BATCH_SIZE).map((companiesSnapshots: QueryDocumentSnapshot[]) => {
const batch = db.batch();
companiesSnapshots.forEach((companySnapshot: QueryDocumentSnapshot) => {
const airportRef = db.collection('companies').doc(companySnapshot.id).collection('airports').doc(airportId);
if (newAirportData) {
batch.set(airportRef, newAirportData, {merge: true});
} else {
batch.delete(airportRef);
}
});
return batch.commit();
});
await Promise.all(batches);
console.log('Airport ', airportId, ' successfully updated.');
} catch (error) {
console.error('Airport ', airportId, newAirportData.name, ' update failed.', error);
}
}
async function getCompanies(): Promise<QueryDocumentSnapshot[]> {
const companies = await db.collection('companies').get();
return companies.docs;
}
Это работает хорошо, но я действительно не уверен насчет производительности или затрат. Рекомендуется ли обновлять документы таким образом?