如何在Firebase firestore中使用orderBy子句查询文档中的两个对象
我有一个文档结构如下的集合:如何在Firebase firestore中使用orderBy子句查询文档中的两个对象,firebase,firebase-realtime-database,google-cloud-firestore,Firebase,Firebase Realtime Database,Google Cloud Firestore,我有一个文档结构如下的集合: { departments: { dept1: true, dept2: true }, roles: { role1: true, role2: true }, created_at: timestamp } 如何查询上述集合,以获取按时间戳排序的dept1和role1的所有文档 我在这里查看了firebase文档 但它只解决了在查询文档中的单个对象时如何获
{
departments: {
dept1: true,
dept2: true
},
roles: {
role1: true,
role2: true
},
created_at: timestamp
}
如何查询上述集合,以获取按时间戳排序的dept1和role1的所有文档
我在这里查看了firebase文档
但它只解决了在查询文档中的单个对象时如何获得有序结果的问题
此外,如果这种文档结构不可能实现,那么我应该如何构造文档/集合,以高效的方式获得所需的结果,因为这将是应用程序中最常见的查询
提前感谢。如果您在Firebase控制台中为其创建索引,您肯定能够进行以下查询
this.refCollection.where('departaments.dept1', '==',true).where('roles.role1', '==', true).orderBy('timestamp')
但是这种方法在您的情况下不起作用,因为您希望动态地向数据库中添加数据,因此每次添加新部门或角色时创建新索引是不切实际的。解决这个问题的一个办法是对数据库进行非规范化
您可以遵循此示例并根据您的情况进行调整:
首先为添加的每个部门创建一个字段,如下所示
部门角色1时间戳:1514925588675
您的文档如下所示:
{
departments: {
dept1: true,
dept2: true
},
roles: {
role1: true,
role2: true
},
created_at: timestamp
}
然后创建一个类似这样的方法,通过参数传递希望从数据库中获取的部门和角色
getDocumentsByDepartamentAndRole(dept, role) {
return this.collectionRef.orderBy(`${dept}_${role}_timestamp`).get();
}
现在,您可以动态搜索,而无需为添加的每个新部门创建索引。通常,当我们需要保证更好的读取性能时,我们会对数据库进行非规范化。但请记住,写操作会降低性能,因为每次要更新部门的角色时,都必须更新为其创建的额外字段,以使查询成为可能。
另一个解决方案是在客户端对数组进行排序。两种方法都会奏效
默认情况下,Firestore不需要为仅使用相等子句的查询提供额外的索引,这显然不是您的情况,因为您使用的是range子句
要了解Firestore索引如何工作的更多信息,您可以阅读。
ref.where(“departments.dept1”、“=”,true)。where(“roles.role1”、“=”,true)。orderBy(“timestamp”)
?根据提供的文档链接,给出一个对象属性timestamp,例如roles.role1=22423425,然后orderBy将工作,但是这种方法不适用于两个对象键:(啊,我已经想知道为什么另一个示例建议它可以(因为我不知道后端如何有效地实现它)。在这种情况下,您必须在客户端按时间戳进行订购。感谢Mateus Forgiarini da Silva,这是可行的。但问题是部门和角色会动态添加到文档中,因此无法在之前创建索引:(.我想我需要用不同的文档设计来处理这个问题。胡姆,明白你的意思了,我更新了答案,你可以通过对数据库进行非规范化来进行查询。这种技术在实时数据库中使用,因为在实时数据库中,你的查询一次只能按一个键进行过滤。只需按照示例进行操作,它就会起作用:)感谢Mateus Forgiarini da Silva,他创造了保持平面结构正常工作的钥匙。