Firestore子集合中按geohash7数组执行Where查询的实现咨询
一、代码报错的原因与修复
你遇到的Property 'collection' does not exist on type 'CollectionReference<DocumentData>'错误,是因为Firestore的API调用层级错误:
Firestore的层级关系是集合 → 文档 → 子集合,firestore().collection('leads')返回的是集合引用,集合引用只能通过.doc(admin_id)获取对应的文档引用,再通过文档引用调用.collection(子集合名)获取子集合。
假设你的数据结构是:leads(集合)→ ${admin_id}(文档)→ 目标子集合(比如命名为targetLeads)→ 目标文档,那么正确的代码应该是:
firestore().collection('leads').doc(admin_id).collection('targetLeads')
二、你的查询需求完全可以在Firestore实现
根据你的需求,有两种最优实现方式,无需冗余数据:
方式1:使用集合组查询(适合子集合同名的场景)
如果每个${admin_id}文档下的子集合都用同一个名字(比如统一叫targetLeads),可以用Firestore的集合组查询,一次性查询所有该名字的子集合中符合条件的文档:
db.collectionGroup('targetLeads') .where('coordinate.geohash7', 'in', ['指定的geohash7数组'])
注意:首次执行该查询时,Firestore会提示你创建集合组索引,直接在控制台点击提示的链接完成创建即可。
方式2:调整数据结构(更推荐,灵活性更高)
如果你的子集合名字不统一,或者希望后续查询更灵活,建议调整数据结构:
把所有目标文档放在一个统一的集合(比如allLeads)中,每个文档新增一个admin_id字段标记所属管理员。此时查询可以同时过滤管理员和geohash条件:
db.collection('allLeads') // 如果需要指定特定管理员,添加这一行;如果查所有管理员则去掉 .where('admin_id', 'in', ['需要查询的admin_id数组']) .where('coordinate.geohash7', 'in', ['指定的geohash7数组'])
这种结构的可查询性更强,维护成本更低,是Firestore数据建模的常规方案。
三、关于你的备选方案
你提到的两种冗余数据的方案都没必要,上述两种方式都能高效解决你的需求,避免数据重复和额外的查询开销。
内容的提问来源于stack exchange,提问作者Jonathan Piquard

