使用映射字段降低索引费用
本页面介绍如何使用映射字段来管理一组子字段的索引设置。
最佳做法是移除未使用的索引,以减少存储费用并提升写入性能。默认情况下,Firestore 会为文档中的每个字段构建一个单字段索引。您可以通过定义索引例外项来控制单字段索引,但每个数据库最多只能有 200 个单字段索引例外项。在停用所有未使用的单字段索引之前,可能会达到此上限。
您可以将具有相同索引要求的文档字段分组到一个映射字段下,从而避免达到例外项上限。然后,您可以向该映射字段应用索引例外项,这一例外项也会应用于映射字段的子字段。
解决方案:使用映射字段帮助管理索引
假设某个应用依赖于一组 game_event
文档。请考虑以下两种数据模型:
顶级文档字段
Node.js
db.collection('game_events').doc().set({ timestamp: Firestore.FieldValue.serverTimestamp(), user_id: 'huDIl8H88kFAFAdcHayf', team_id: '6Q5BhBESeTPk8LT0O59I', event_type: 'rare_item_drop', display_text: 'You found a rare item!', });
映射字段和子字段
在此数据模型中,所有文档字段都成为 details
字段的子字段:
Node.js
db.collection('game_events').doc().set({ details: { timestamp: Firestore.FieldValue.serverTimestamp(), user_id: 'huDIl8H88kFAFAdcHayf', team_id: '6Q5BhBESeTPk8LT0O59I', event_type: 'rare_item_drop', display_text: 'You found a rare item!', } });
假设此应用始终根据 user_id
和 timestamp
或者 team_id
和 timestamp
查询 game_event
文档。例如:
Node.js
let query_user_events = db.collection('game_events') .where('details.user_id', '==', 'huDIl8H88kFAFAdcHayf') .orderBy('details.timestamp'); let query_team_events = db.collection('game_events') .where('details.team_id', '==', '6Q5BhBESeTPk8LT0O59I') .orderBy('details.timestamp');
请注意有关此应用的以下事项:
- 应用依赖于
details.user_id, timestamp
和details.team_id, timestamp
的复合索引。 - 应用不使用
timestamp
、user_id
、team_id
、event_type
或display_text
的单字段索引。
基于这些索引要求,最好是停用 timestamp
、user_id
、team_id
、event_type
或 display_text
的单字段索引。现在来比较一下这两个数据模型所需的例外项。
停用顶级字段的索引
要停用顶级字段数据模型中的单字段索引,您必须为每个字段定义一个例外项。您的例外项数量增加了五个,您每向数据模型添加一个新字段,都必须再定义一个例外项来停用其单字段索引。
停用子字段的索引
要停用映射字段和子字段数据模型的单字段索引,您可以为映射字段定义一个例外项。映射字段的例外项会将同样的索引设置应用于该映射字段的子字段。如果您为 details
字段添加一个新的子字段,则例外项会自动停用新子字段的单字段索引。
例如,使用 Firebase CLI 为 firestore.indexes.json
文件添加相应的索引例外项后,系统会停用 game_events
集合的单字段索引:
{ "collectionGroup": "game_events", "fieldPath": "details", "indexes": [] },
如果您以后需要某个子字段的单字段索引,则可以使用例外项覆盖映射字段的索引设置。子字段的例外项会覆盖该子字段继承的索引设置。例如:
{ "collectionGroup": "game_events", "fieldPath": "details.event_type", "indexes": [ { "order": "ASCENDING", "queryScope": "COLLECTION" }, ] },
何时使用此方法
在上面的示例中,映射字段和子字段方法将例外项数量从 5 个减为 1 个。假设有一个类似的文档数据模型,其中包含 200 个字段。那么此方法可将例外项数量从 200 个减少到 1 个。
如果文档数据模型包含多个带有未使用单字段索引的字段,您应该考虑使用映射字段和子字段方法。对于包含许多字段的文档,尤其应该考虑这种方法。