Firebase Realtime Database多值字段orderBy查询实现咨询
问题解答
一、过滤特定城市任务的可行性
两种存储结构都能实现过滤需求,但实现方式和效率有明显区别:
1. 海报对象数组结构
Realtime Database无法直接通过服务端查询数组内嵌套对象的属性来过滤父节点,要实现需求有两种思路:
- 客户端二次过滤:先查询所有任务数据,在本地遍历每个任务的
posters数组,检查是否存在包含目标城市的对象。 - 调整数据结构:将
posters从数组改为以城市名为键的对象,或者给任务新增一个专门用于查询的城市列表字段,示例如下:
调整后可结合客户端逻辑更高效地完成过滤。{ "posters": { "Toronto": {"id": "axf"}, "Montreal": {"id": "axf"}, "Calgary": {"id": "axf"} }, "associatedCities": ["Toronto", "Montreal", "Calgary"] }
2. 城市名称拼接字符串结构
这种结构同样无法通过服务端查询直接匹配子串,只能在客户端获取全部任务数据后,用字符串匹配方法(比如JavaScript的includes())筛选包含目标城市的任务。缺点是服务端会返回所有任务数据,传输量更大,整体效率偏低。
二、Realtime Database的orderBy查询是否支持正则表达式?
不支持。Realtime Database的查询API(包括orderByChild、equalTo等方法)完全不支持正则表达式匹配。你尝试的equalTo(".*Toronto.*")写法无效,它只会精确匹配字符串".*Toronto.*",不会将其作为正则表达式解析。
三、优化方案
如果希望在服务端完成过滤、减少客户端的数据处理量,推荐调整数据结构:
- 给每个任务新增一个
cityList数组字段,存储关联的城市名称,同时在数据库规则中为该字段配置索引(如果存在大量查询需求)。 - 或者采用反向索引结构:单独维护一个
cityToJobs节点,键为城市名称,值为包含该城市的任务ID列表,示例如下:
这种方式可以直接通过{ "cityToJobs": { "Toronto": ["job_axf", "job_bxg"], "Montreal": ["job_axf", "job_cxh"] } }child("cityToJobs/Toronto")获取所有关联任务的ID,再查询对应任务详情,效率是最高的。
内容的提问来源于stack exchange,提问作者user1743524
相关产品推荐
相关产品推荐

