如何使用Firebase firestore中的orderBy子句查询文档中的两个对象

Gan*_*pat 2 firebase firebase-realtime-database google-cloud-firestore

我有一个文件结构的集合,如下所示:

{
    departments: {
        dept1: true,
        dept2: true
    },
    roles: {
        role1: true,
        role2: true
    },
    created_at: timestamp
}
Run Code Online (Sandbox Code Playgroud)

如何查询上面的集合以获取dept1和role1按时间戳排序的所有文档.

我在https://firebase.google.com/docs/firestore/solutions/arrays上查看了firebase文档

但它只回答了当我们查询文档中的单个对象时如何获得有序结果.

此外,如果它不可能与这个文档结构,那么我应该如何构建文档/集合以高效的方式获得所需的结果,因为这将是在App中最频繁的查询

提前致谢.

Mat*_*lva 5

如果您在Firebase控制台中为其创建索引,则可以在下面进行查询.

this.refCollection.where('departaments.dept1', '==',true).where('roles.role1', '==', true).orderBy('timestamp')
Run Code Online (Sandbox Code Playgroud)

但是,这种方法在您的情况下不起作用,因为您希望动态地将数据添加到数据库中,因此每次添加新的部门或角色时创建新索引都是不切实际的.解决方案是对数据库进行非规范化.

您可以按照此示例并适应您的情况:

首先为每个部门创建一个字段,如下所示.

dept1_role1_timestamp:1514925588675

您的文档如下所示:

在此输入图像描述

然后创建一个像这样的方法,您可以通过参数传递要从数据库中获取的部门和角色.

getDocumentsByDepartamentAndRole(dept, role) {
    return this.collectionRef.orderBy(`${dept}_${role}_timestamp`).get();
}
Run Code Online (Sandbox Code Playgroud)

现在,您将能够动态搜索,而无需为添加的每个新部门创建索引.通常,当我们需要保证更好的读取性能时,我们会对数据库进行非规范化.但请记住,您的写入会失去性能,因为每次您想要更新部门的角色时,您都必须更新您创建的额外字段以使查询成为可能.另一种解决方案是在客户端对数组进行排序.两种方式都有效.

默认情况下,对于仅使用相等子句的查询,Firestore不需要其他索引,显然不是这种情况,因为您正在使用范围子句.

要了解有关Firestore索引如何工作的更多信息,您可以阅读文档.