更新 2020-01-23:
有关这方面的更新,请参阅群组板上与 Sam Stern 的对话:https : //groups.google.com/d/msgid/google-cloud-firestore-discuss/e1b47358-b106-43a0-91fb-83c97d6244de%40googlegroups。电脑
大部分讨论来自一个明显的事实,即基于文档的完全限定路径(因此只需要在“集合中”唯一),数据库中的所有记录都有一个“主索引”。
为了“加速”文档引用,JS SDK 实际上将集合路径“前置”到 .doc 中传递的任何信息上,以“方便地”使用该主索引
即所有这些都是完全等效的
db.doc('collection/docId/collection/docId/collection/docId")
db.collection('collection").doc("docId/collection/docId/collection/docId")
db.collection('collection").doc("docId").collection("collection").doc("docId/collection/docId")
db.collection('collection").doc("docId").collection("collection").doc("docId").collection("collection").doc("docId")
db.doc("collection/docId").collection("collection").doc("docId").collection("collection").doc("docId")
db.collection("collection/docId/collection").doc("docId").collection("collection").doc("docId")
db.doc("collection/docId/collection/docId").collection("collection").doc("docId")
db.collection("collection/docId/collection/docId/collection").doc("docId")
--- 他们都创建了相同的索引引用“collection/docId/collection/docId/collection/docId”以在“主索引”中查找文档。
(在我一点也不谦虚的意见中) FieldPath.documentId() 被实现(错误地)以“方便地”匹配此行为,因此需要完全限定的路径,而不是 docId,当它应该像任何一样实现时其他查询,并且需要创建和维护一个 NEW INDEX 来容纳该查询。
此行为的代码是在实现 collectionGroups 之前编写的 - 并且从未记录过使用的 hack 与使用的 METHOD NAME 不匹配。
解决方法是要求编码器将 docId 作为字段复制到每个文档中,并在其上编写您的查询。我已经在 Firestore.js 和我的应用程序之间编写了自己的层来抽象行为,并且可能只是将其实现为库的基本功能。
但这显然是一个错误,到目前为止,每个人都一直试图告诉我这是有道理的,并且他们将更改文档以匹配现有行为(但不是方法名称)。
正如我之前写的那样,我不断收到一堆破烂的雏菊,并被告知“看到了吗?这些是玫瑰!文件称它们为玫瑰!任何其他名字的玫瑰闻起来都很甜,等等!!”
除非他们感到尴尬,否则不会更新
2020 年 1 月 10 日更新:我构建了一个演示应用程序,显示了确切的错误,并已根据要求将其发送给 Firebase 支持。出于某种原因,支持小动物将其视为“功能请求”,尽管它显然是一个错误。当以“/ShowInfo/showID”形式调用 URL 时,应用匿名登录 Firebase Auth;然后使用 FieldPath.documentId() "==" showID 在 collectionGroup(3 层深)上调用查询
它使查询 3 种方式:
1) 仅使用 showID- 时会因熟悉的“无效查询”而失败。当通过 FieldPath.documentId() 查询集合组时,提供的值必须产生有效的文档路径,但 'pqIPV5I7UWne9QjQMm72'(实际的 showID)是不是因为它有奇数个段 (1)。”
2) 使用“相对路径”(/Shows/showID) 一次,它没有错误,但不返回任何文档。
3) 最后使用“完整路径”(/Artists/ArtistID/Tour/tourID/Shows/showID)。这没有错误,并且确实返回了一个文档 - 但是如果我有完整路径,为什么我需要在 collectionGroup 上进行查询?而且我没有完整路径 - showID(上面)作为 URL 的一部分(显然是节目数据的链接)出现 - 我为测试手工伪造了它。
等待回应。
2019 年 12 月 2 日更新:Firebase 支持人员联系我询问我是否仍希望解决此问题。呃。
更新 2019-09-27:Firebase 支持人员承认这是一个错误。什么时候修好还没有说。实际上,documentId()应该能够仅直接用于文档 ID。
documentID可以用作查询的一部分,但正如上面@greg-ennis 所指出的,它需要偶数个段。事实证明,如果您确实需要一个 collectionGroup(我确实需要),那么要比较的“Id”需要将 collectionGroup ID/name冗余添加为一个段:
db.collectionGroup('likedBy')
.where(firebase.firestore.FieldPath.documentId(), '==', "likedBy" + "/" + "User A")
.get();
我用过它并且它(*sorta)有效。(诚然,我花了 2 个小时才弄明白,上面的问题有助于集中搜索)
另一方面,这种特定情况不是您想要使用 collectionGroup 的地方。记住采集组是-指AA组的方式单独收集,好像他们是一个。在这种情况下,保存“用户 A”喜欢的“集合”作为“用户 A”文档下的集合存在。在删除“用户 A”的文档之前,只需删除该单个集合。没必要把其他人的喜好都带进来。
Sorta:显然比较的字段路径必须是文档的完整路径。如果您知道 documentId,但由于“原因”,您不知道完整路径,包括子集合所属的文档(这就是为什么您首先使用 collectionGroup 方法的原因),现在这似乎有点死路。继续努力。
验证和错误报告提交:FieldPath.documentID()并没有针对documentId比较; 它与完全分段的文档路径进行比较,正如您必须提供给 .doc(path) 一样:
即:在“TopCollection/document_this/NextCollection/document_that/Travesty/document_Id_I_want”中找到一个文档
使用集合组“Travesty”
db.collectionGroup("Travesty")
.where(firebase.firestore.FieldPath.documentId(), '==', "document_id_I_want")
……会失败,但是……
db.collectionGroup("Travesty")
.where(firebase.firestore.FieldPath.documentId(), '==', "TopCollection/document_this/NextCollection/document_that/Travesty/document_Id_I_want")
.get()
……会成功的。这使得这毫无用处,因为如果我们拥有所有这些信息,我们将只使用:
db.doc("TopCollection/document_this/NextCollection/document_that/Travesty/document_Id_I_want")
.get()