Проблема с Firestore 500 пишет в пакетном пределе - PullRequest
0 голосов
/ 08 апреля 2020

Я разрешаю импорт данных, что дает мне большое количество документов для записи в firestore. Я держу счетчик документов, поэтому я должен замедлить запись.

// process 75 contacts every 1200ms
return new Promise<boolean>(async (resolve, reject) => {
      timer(0, 1200)
        .pipe(
          takeWhile((_) => !!contacts.length),
        )
        .subscribe(async () => {
          const next = contacts.splice(0, 75);
          await updateContacts(userId, next);
        });
    });

Обновление контакта работает следующим образом: -

// It updates three documents: Basic, Extended and the User doc
// which has the count
export async function updateContacts(userId: string, contacts: Contact[]) {
  const firestore = admin.firestore();
  const batch = firestore.batch();
  const userRef = getUserRef(userId);

  for (const contact of contacts) {
    const basicRef = getBasicContactRef(userId);
    const extendedRef = getDetailContactRef(userId, basicRef.id);

    const basic = contact.getBasic();
    batch.set(basicRef, {
      ...basic,
      ...{ timestamp: FieldValue.serverTimestamp() },
    });

    const extended = contact.getExtended();
    batch.set(extendedRef, {
      ...extended,
      ...{ timestamp: FieldValue.serverTimestamp() },
    });

  }

  // Now update the count
  batch.update(userRef, {
    numberOfContacts: FieldValue.increment(contacts.length),
  });

  // commit it all
  return batch.commit();
}

Однако, когда я запускаю его с большим количеством контактов, происходит сбой со следующим: -

Ошибка: 3 INVALID_ARGUMENT: разрешено максимум 500 записей на один запрос

Я думал, что я выполняю менее 500 записей на запрос!

Я действительно чешу голову, пытаясь выяснить. Я не слишком умен, поэтому прошу вас мудрых людей. Есть идеи, что я делаю не так?

1 Ответ

2 голосов
/ 08 апреля 2020

У меня есть догадка, проблема в том, что преобразования полей применяются вашим полем. Ограничение 500 основано на количестве мутаций , а не на операциях с документами верхнего уровня. Я посмотрел внутренний код, который преобразует операции пакетного обновления / установки в мутации, и в некоторых случаях есть коэффициент удвоения:

https://github.com/firebase/firebase-js-sdk/blob/9bc4167d5895099ff60fd75d462cbb0d9fd8429e/packages/firestore/src/api/user_data_reader.ts#L101

Так что вы можете видеть, что ваш пакет из 75 генерирует как минимум 2 мутации для batch.set (basicRef), дополнительные 2 мутации для batch.set (extendedRef) и т. Д. c. Могут быть и другие скрытые затраты, которые я еще не отслеживал, которые увеличивают общее число мутаций до> 500.

Возможно ли, чтобы вы сократили количество документов (контактов), которые вы передаете updateContacts ()?

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