我有一个文档结构如下的集合:
{
departments: {
dept1: true,
dept2: true
},
roles: {
role1: true,
role2: true
},
created_at: timestamp
}
如何查询上面的集合以按时间戳顺序获取具有dept1和role1的所有文档。
我在这里检查了firebase文档
https://firebase.google.com/docs/firestore/solutions/arrays
但这仅回答当我们查询文档中的单个对象时如何获得有序的结果。
另外,如果此文档结构无法实现,那么我应该如何结构化文档/集合以高效的方式获得所需结果,因为这将是App中最常见的查询
提前致谢。
最佳答案
如果您在Firebase控制台中为其创建索引,则绝对可以在下面进行查询。
this.refCollection.where('departaments.dept1', '==',true).where('roles.role1', '==', true).orderBy('timestamp')
但是,这种方法在您的情况下不起作用,因为您想将数据动态地添加到数据库中,因此每次添加新的部门或角色时创建新索引都是不切实际的。一种解决方案是对数据库进行非规范化。
您可以按照以下示例并适应您的情况:
首先为每个部门创建一个字段,如下所示。
dept1_role1_timestamp:1514925588675
您的文档如下所示:
然后创建一个类似这样的方法,在该方法中,您可以通过参数传递要从数据库中获得哪个部门和角色。
getDocumentsByDepartamentAndRole(dept, role) {
return this.collectionRef.orderBy(`${dept}_${role}_timestamp`).get();
}
现在,您将能够动态搜索,而不必为添加的每个新部门创建索引。通常,当我们需要保证更好的读取性能时,我们会对数据库进行非规范化。但是请记住,您的写操作会降低性能,因为每次您要更新部门的角色时,都必须更新创建的额外字段以使查询成为可能。
另一个解决方案是在客户端对数组进行排序。两种方式都可以。
默认情况下,Firestore不需要仅使用相等子句的查询的其他索引,显然,由于要使用range子句,因此情况并非如此。
要了解有关Firestore索引如何工作的更多信息,可以在documentation上阅读。