Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/jenkins/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Firebase firestore中使用orderBy子句查询文档中的两个对象_Firebase_Firebase Realtime Database_Google Cloud Firestore - Fatal编程技术网

如何在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,他创造了保持平面结构正常工作的钥匙。