如何删除Firestore自动生成的单字段索引?

时间:2018-07-12 08:36:07

标签: firebase google-cloud-firestore

更新:
   TLDR;

如果到达此处,则应重新检查构建数据库的方式。 您的文档可能随着时间的流逝而耗费时间(由于嵌套列表等)。

原始问题:
我收集了很多领域的文件。我不查询文件,甚至没有简单的查询- 我只使用-

db.collection("mycollection").doc(docName).get().then(....);

为了阅读文档, 所以我不需要为这个集合做任何索引。

问题在于,firestore会自动生成单一字段索引,并且由于字段数量过多,导致超出索引限制: enter image description here 而且,如果我尝试向其中一个文档添加字段,则会引发错误:

Uncaught (in promise) Error: Too many indexed properties for entity: app: "s~myapp",path <  Element {    type: "tags",    name: "aaaa"  }>
    at new FirestoreError (index.cjs.js:346)
    at index.cjs.js:6058
    at W.<anonymous> (index.cjs.js:6003)
    at Ab (index.js:23)
    at W.g.dispatchEvent (index.js:21)
    at Re.Ca (index.js:98)
    at ye.g.Oa (index.js:86)
    at dd (index.js:42)
    at ed (index.js:39)
    at ad (index.js:37)

我找不到删除这些单字段索引或告诉Firestore停止生成它们的任何方法。 我在Firestore控制台中找到了这个: enter image description here

,但是无法禁用它,也不能禁用特定集合的自动索引。 有办法吗?

4 个答案:

答案 0 :(得分:2)

简短的答案是,您现在无法使用Firebase做到这一点。但是,这很好地表明了您需要重组数据库模型,以避免达到诸如每个文档1MB的限制。

文档讨论了数据限制:

  

您不能在嵌套列表上运行查询。另外,这不像   与其他选项一样具有可扩展性,尤其是当您的数据随时间扩展时。   随着列表的增加或增长,文档也会增长,这可能导致   缩短文档检索时间。

请参阅此页面,以了解有关用于构建数据的不同策略的优缺点的更多信息:https://firebase.google.com/docs/firestore/manage-data/structure-data

答案 1 :(得分:2)

您可以在Firestore 中删除简单的索引。

有关创建和删除索引的最新信息,请参见此答案。

Firestore composite index permutation explosion?

如果在选择Firestore数据库后进入“索引”,然后选择“单个”索引,则有一个“添加免除”按钮,可用于指定集合(或子集合)中哪些字段具有由Firestore生成的简单索引。您必须指定“集合”,然后指定该字段。然后,由于无法指定整个集合,因此请分别指定每个字段。似乎没有检查有效的集合或字段名称。

我认为检查此方法是否有效的唯一方法是使用该字段进行查询,并且该查询将失败。

我在其中包含普通文本的大型字符串字段上执行此操作,因为它们将花费很长时间进行索引,而且我知道我永远不会使用此字段进行搜索。

Firestore会为每个简单字段(升序和降序)创建两个索引,但是如果您永远不需要第二个索引,则可以创建一个豁免,从而删除其中的一个索引,这有助于提高性能并减少点击的可能性。指数限制。另外,您可以选择是否对数组建立索引。如果您在一个数组上创建很多条目,那么很快就会达到索引数量的存储限制,因此在使用索引时必须格外小心,因为从设计者的角度出发,通常最好将索引从数组中删除可能无法控制添加了多少Array数据项,结果达到了最大索引限制,并且应用程序将收到错误,如原始发布者所述。

即使未在复杂索引中包含字段,也可以删除任何不使用的简单索引。复杂索引仍然可以使用。

其他需要注意的事情。

如果您为时间戳字段(或文档之间顺序增加或减少的任何字段)建立索引,并且没有使用该字段来强制查询中的序列,则该集合的最大写入速率为每秒500次写入。在这种情况下,可以通过删除增加和减少的索引来消除此限制。

请注意,与实时数据库不同,使用自动ID创建的字段不保证任何顺序,因为它们是由Firestore生成的,用于分散写入,并避免热点或瓶颈,因为所有写入(以及读取)最终都集中在一个位置。这意味着通常需要时间戳来生成排序,但是您可以设计集合/子集合的数据布局,从而避免使用时间戳。例如,如果您使用时间戳记来查找最后一个添加到集合中的文档,则最好存储最后添加的文档的ID。

大数组或映射字段还可以使每个文档的索引条目达到20,000个限制,因此您可以免除数组的索引编制(请参见下面的屏幕截图)。

enter image description here

添加了一项豁免后,您将获得此屏幕。 Exemption screen once one has been added

也请参见此链接。

https://firebase.google.com/docs/firestore/query-data/index-overview

答案 2 :(得分:0)

如Firestore文档中所述:

  

Cloud Firestore要求每个查询都有一个索引,以确保最佳性能。所有文档字段都将自动建立索引,因此仅使用相等子句的查询不需要其他索引。如果尝试使用不映射到现有索引的range子句进行复合查询,则会收到错误消息。该错误消息包括一个直接链接,用于在Firebase控制台中创建缺少的索引。

您可以使用要保存的结构数据来更新您的问题吗?

您的问题的一种解决方法是创建复合索引,或者作为最后的资源,Firestore可能不适合您的应用程序需求,Firebase Realtime Database可能是更好的解决方案。

请参阅权衡: RTDB vs Firestore

答案 3 :(得分:0)

我不认为当前存在您要查找的开关,所以我认为剩下了以下内容,

  1. 全局禁用内置索引并显式创建所有索引。痛苦的,他们也有极限。

  2. 一种变通方法,您可以将Cloud Firestore不友好的内容视为BLOB,例如:

要存储,

const objIn = {text: 'my object with a zillion fields' };
const jsonString  = JSON.stringify(this.objIn);
const container = { content: this.jsonString };

要检索,

const objOut = JSON.parse(container.content);