Firestore 查询已删除文档的子集合

Firestore query for subcollections on a deleted document

使用 Firebase 控制台时,可以查看所有文档和集合,甚至是路径中 "documents" 不存在的子集合。

这在此处包含的图片中进行了说明,如文档和屏幕截图中所述。这些文档不会出现在查询或快照中。那么当查询没有 return 它们时,控制台如何找到这些嵌套的子集合呢?

是否可以以某种方式列出这些文件。控制台既然可以做到,看来一定是有办法的。 如果可以找到这些文档,是否可以创建一个查询来获取所有不存在但仅限于具有嵌套子集合的文档? (因为所有不存在的文档的集合将是无限的)

Is it possible to create a query that fetches all these subcollections that are nested under a document that does not exist.

Cloud Firestore 中的查询很浅,这意味着它们仅从查询 运行 所针对的集合中获取文档。 Cloud Firestore 无法在单个查询中从顶级集合 其他集合或子集合中获取文档。 Firestore 不支持一次跨不同集合的查询。单个查询只能使用单个集合或子集合中的文档属性。

因此,在您的情况下,即使一个文档不存在(不包含任何属性),您仍然可以查询位于其下的集合。换句话说,您可以查询 -LFNX ... 7UjS 文档中存在的 queue 子集合,但 不能 查询所有文档中的所有 queue 子集合。您一次只能查询一个子集合。

编辑:

根据您的评论:

I want to find collections that are nested under documents that do not exist.

无法找到集合s,因为您无法跨不同的集合进行查询。您只能 查询一个。我能想到的最简单的解决方案是检查 items 集合中的文档是否不存在(没有属性),然后创建查询 (items -> documentId -> queue),并检查是否有任何结果。

编辑2:

Firebase 控制台通过 斜体 中显示的文档 ID 告诉您这些文档 存在。这些文档不存在,因为您根本没有创建它们。您所做的只是 在最初不存在的文档下创建子集合。换句话说,它只是 "reserves" 该集合中文档的 id,然后在其下创建子集合。通常,您应该只创建实际 do 存在的文档的子集合,但这是文档不存在时的样子。

在 Cloud Firestore 中,文档和子集合不像您使用的文件系统文件和目录那样工作。如果您在文档下创建子集合,它不会隐式创建任何父文档。子集合不以任何方式绑定到父文档。换句话说,那个位置没有物理文件但是这个位置下还有其他数据。

在 Firebase 控制台中显示了这些文档 ID,因此您可以向下导航树并获取其下存在的子集合和文档。但与此同时,控制台通过在 斜体 中显示它们的 ID 来警告您这些文档不存在。所以你不能显示或使用它们,因为一个简单的事实,即它下面没有数据。如果你想纠正它,你必须至少写一个 属性 可以保存一个值。这样一来,这些文档将保存一些数据,因此您可以做任何您想做的事情。

P.S。在 Cloud Firestore 中,如果您删除文档,其子集合将继续存在,这是因为我上面提到的完全相同的原因。

Admin SDK 提供了一个 listDocuments 方法,其描述如下:

The document references returned may include references to "missing documents", i.e. document locations that have no document present but which contain subcollections with documents. Attempting to read such a document reference (e.g. via .get() or .onSnapshot()) will return a DocumentSnapshot whose .exists property is false.

将此与 example for listing subcollections 相结合,您可以执行以下操作:

// Admin SDK only
let collectionRef = firestore.collection('col');

return collectionRef.listDocuments().then(documentRefs => {
   return firestore.getAll(documentRefs);
}).then(documentSnapshots => {
   documentSnapshots.forEach(doc => {
      if( !doc.exists ) {
        console.log(`Found missing document: ${documentSnapshot.id}, getting subcollections`);
        doc.getCollections().then(collections => {
          collections.forEach(collection => {
            console.log('Found subcollection with id:', collection.id);
          });
        });
      }
   });
});

请注意,Firebase CLI 使用不同的方法。通过 REST API,它查询给定路径下的所有文档,而不必首先知道它们的具体位置。您可以在递归删除代码 here.

中看到它是如何工作的