Google Datastore(Datastore模式Firestore)嵌套数组查询与索引问题
结论
你提出的两个需求无法直接通过原生GQL查询返回你要求的格式化结果,Datastore模式的GQL本身不支持嵌套数组的自动扁平化,也不支持直接提取嵌套数组内的指定字段作为返回结果。你可以通过提前冗余字段+GQL查询的方案实现最高效率,完全避免全量拉取实体后再过滤的性能问题。
需求1实现方案(返回id/date/subarray_content列表)
- 提前在实体顶层新增冗余字段
all_subarrays,类型为数组。每次写入/更新实体时,自动遍历array下所有元素,将每个元素的subarray内容全部扁平存入该字段。 - 直接使用GQL投影查询,仅返回你需要的字段:
SELECT id, date, all_subarrays FROM 你的Kind名称 WHERE id = @指定id AND date > DATETIME("2021-10-19T20:00:00.00000+02:00") - 查询返回后直接取出
all_subarrays字段即可使用,不需要额外处理。
所需索引
创建id + date的升序复合索引即可,不需要特殊的数组索引。
需求2实现方案(返回id/date/itemid/subparam1列表)
- 提前在实体顶层新增冗余字段
flatten_subparam_list,类型为对象数组。每次写入/更新实体时,遍历所有array元素及其内部的subarray子元素,将每个子项组装为{"itemid": 所属上层item的itemid, "subparam1": 当前子项subparam1值}的结构,全部存入该字段。 - 使用GQL投影查询:
SELECT id, date, flatten_subparam_list FROM 你的Kind名称 WHERE id = @指定id AND date > DATETIME("2021-10-19T20:00:00.00000+02:00") - 返回的
flatten_subparam_list就是你需要的结果。
所需索引
和需求1共用同一个id + date的复合索引即可,不需要额外创建索引。
折中方案(无冗余字段)
如果你不想修改现有数据结构做字段冗余,也可以用GQL投影查询仅返回id、date、array三个字段,相比拉取完整实体可以大幅减少网络传输的数据量,之后仅需要在代码中做一次轻量遍历提取即可,性能远优于全量拉取实体后过滤的方案,对应GQL如下:
SELECT id, date, array FROM 你的Kind名称 WHERE id = @指定id AND date > DATETIME("2021-10-19T20:00:00.00000+02:00")
内容的提问来源于stack exchange,提问作者aregnier
相关产品推荐
相关产品推荐

