Как найти все экземпляры документа в нескольких подколлекциях в базе данных firestore? - PullRequest
0 голосов
/ 10 апреля 2020

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

Например, в примере покупок с несколькими пользователями, каждый из которых имеет вложенную коллекцию с корзиной, списком пожеланий и владельцем. Идентификатор документа может существовать или не существовать в каждом из подколлекций пользователя c. Я пытаюсь написать функцию, которая выполняет итерацию по этим спискам и выполняет действие при сопоставлении docID, но пока не удалось найти пример этого.

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

Моя первоначальная мысль:

    let batch = admin.firestore().batch();
    let allUsers = db.collection('users').get()
      .then(snapshot => {
        snapshot.forEach(doc => {
          batch.delete(db.collection('users').doc(doc.id).collection('cart').doc(ID_TO_MATCH));
          batch.delete(db.collection('users').doc(doc.id).collection('wishlist').doc(ID_TO_MATCH));
          batch.delete(db.collection('users').doc(doc.id).collection('owned').doc(ID_TO_MATCH));
        });
      })
      .catch(err => {
        console.log('Error getting documents', err);
      });
      return batch.commit().then(function () {
          // should delete all the direct referenes
      });

Это сработает, поскольку firestore возвращает успех для удаления документов, которые не завершаются. Очевидным недостатком является МНОГО чтения документов по мере роста числа пользователей. Есть ли способ использовать .where() запросов, чтобы сделать это более эффективным?

1 Ответ

1 голос
/ 10 апреля 2020

Вы можете использовать запрос where() на основе documentId sentinel, как указано ниже:

...collection('cart').where(firebase.firestore.FieldPath.documentId(), '==', ID_TO_MATCH)

, но я не думаю, что это что-то изменит с точки зрения цены или представление. На самом деле, «минимальная плата за чтение одного документа для каждого выполняемого вами запроса, даже если запрос не возвращает результатов», как объяснено в do c. Таким образом, чтение do c с помощью

collection('cart').doc(ID_TO_MATCH)

или с помощью

collection('cart').where(firebase.firestore.FieldPath.documentId(), '==', ID_TO_MATCH)

не имеет никакого значения для IMO.


Другая возможность будет использовать запрос collectionGroup . Проблема, в данном конкретном случае c, заключается в том, что при запросе группы сбора по FieldPath.documentId() предоставленное значение должно привести к допустимому пути документа . См. ТАК сообщение для более подробной информации. Так что это не будет работать с ID_TO_MATCH ...

Но , есть обходной путь: вы можете сохранить в ваших документах поле, которое имеет то же значение, что и идентификатор документа, а затем запрос collectionGroup будет работать.

Итак, с полем docId в вашем документе, которое содержит значение идентификатора документа, вы можете написать следующий запрос:

const cartsQuery = db.collectionGroup('cart').where('docId', '==', ID_TO_MATCH);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...