如何在firestore数据库的多个子集合中查找文档的所有实例



我有一个firestore数据库,它将一些文档按ID存储在多个位置。我想写一个函数,可以通过ID访问该文档的所有实例,并更新/删除它们,而不知道它们到底在哪里。

例如,在一个购物示例中,有多个用户,每个用户都有一个子集合,其中包含购物车、心愿单和owned。文档ID可能存在也可能不存在于用户文档的每个子集合中。我正试图编写一个函数来遍历这些列表,并在匹配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()查询来提高效率?

您可以使用基于documentId sentinel的where()查询,如下所示:

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

但我不认为它会在定价或性能方面有所改变。事实上,正如文档中所解释的,"即使查询没有返回结果,您执行的每个查询也要至少读取一个文档"。所以通过阅读文档

collection('cart').doc(ID_TO_MATCH)

或者通过

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

没有任何区别IMO.


另一种可能性是使用collectionGroup查询。在这种特定情况下,问题是当您通过FieldPath.documentId()查询集合组时,提供的值必须导致有效的文档路径。有关更多详细信息,请参阅此SO帖子。因此,这将不适用于ID_TO_MATCH。。。

但是有一个解决方法:您可以在文档中保存一个与文档ID具有相同值的字段,然后collectionGroup查询就可以工作了。

因此,在文档中有一个字段docId,它包含文档ID的值,您可以编写以下查询:

const cartsQuery = db.collectionGroup('cart').where('docId', '==', ID_TO_MATCH);

相关内容

  • 没有找到相关文章

最新更新