首页 > 解决方案 > 是否可以为这两个查询设计一个 Google Datastore 索引?

问题描述

我想知道是否可以设计谷歌数据存储索引和查询,以减少我的项目所需的复合索引的数量。

我一直在尝试使用一个索引,该索引适用于我的两个查询,例如在此处找到的示例。但是,我找不到一种方法让一个索引满足我的查询需求,我也不知道是否存在一个索引。以下是我一直在使用的两个查询以及我收到的针对这两个查询的数据存储索引建议。我可以做些不同的事情来使这些查询与单个索引一起工作吗?

查询一:

CompositeFilter.and(
    CompositeFilter.and(PropertyFilter.gt("time", time1), PropertyFilter.lt("time", time2)), 
    PropertyFilter.eq("user", user1),
    PropertyFilter.eq("color", color1), 
    PropertyFilter.eq("bpm", bpm1));

addOrderBy(OrderBy.asc("time"), OrderBy.asc("location"));

查询1索引建议:

- name: color
- name: bpm
- name: user
- name: time
- name: location

查询 2:

CompositeFilter.and(
    CompositeFilter.and(PropertyFilter.gt("time", time1), PropertyFilter.lt("time", time2)),
    PropertyFilter.eq("user", user1));

addOrderBy(OrderBy.asc("time"), OrderBy.asc("color"), OrderBy.asc("bpm"), OrderBy.asc("location"));

查询2索引建议:

- name: user
- name: time
- name: color
- name: bpm
- name: location

标签: javagoogle-cloud-datastore

解决方案


我假设“创建”实际上是“时间”,因为您在过滤器中使用“时间”并在排序中使用“创建”。

请注意,任何数据存储查询都应满足对一个(或多个)索引的单范围扫描。

在您的第一个查询中,您固定了用户、颜色和 bpm,并且对于给定的时间范围,您希望按时间和位置进行排序。因此,您需要将用户、颜色和 bpm 作为前缀列,后跟时间和位置。

在您的第二个查询中,您只需固定用户并在给定的时间范围内按时间、颜色、bpm 和位置排序。这意味着,用户是唯一的分区,然后必须立即在给定的时间范围内进行扫描。在这种情况下,颜色和 BPM 随时间出现以支持排序顺序。

这就是为什么不可能摆脱单一索引的原因。但是,如果您要查询的给定用户和时间范围的数据不多,您可以只对用户和时间进行索引,然后在获得结果后进行内存排序。如果您想使用投影查询,那么您将需要所有列和您的第二个索引以及内存过滤(精确的 bpm 和颜色)并且需要排序。


推荐阅读