我知道这是DataStore的限制,但我只想弄清楚原因。我读过bigtable文章,我找不到对不同列上的不等式过滤器的任何限制。它可以支持前缀和范围扫描。恕我直言,DataStore可以通过这两个操作支持多个不等式过滤器。你知道从DataStore获取功能的原因吗?
答案 0 :(得分:7)
To avoid having to scan the entire index table, the query mechanism relies on
all of a query's potential results being adjacent to one another in the index.
To satisfy this constraint, a single query may not use inequality comparisons
(LESS_THAN, LESS_THAN_OR_EQUAL, GREATER_THAN, GREATER_THAN_OR_EQUAL, NOT_EQUAL)
on more than one property across all of its filters
[来源:https://cloud.google.com/appengine/docs/standard/java/datastore/query-restrictions]
答案 1 :(得分:1)
每个数据存储区查询都在一个或多个索引表上运行。
在考虑不等式过滤器时,我们希望在最多一个属性上运行,以避免在整个索引表上运行。在调查过滤器如何工作,datastore-indexes.xml
定义的方式以及索引的准确性时,它更容易掌握:
<datastore-index>
是数据存储应维护的元素,每个索引一个元素。因此,您为实体的类型及其属性之间的每个关系定义一个索引(即表格)。现在想象一下,当你需要计算不同属性的多个不等式过滤器时?它可能导致巨大的运行时间。不好。
<?xml version="1.0" encoding="utf-8"?>
<datastore-indexes autoGenerate="true">
<datastore-index kind="Greeting" ancestor="true" source="manual">
<property name="user" direction="asc" />
<property name="birthYear" direction="asc" />
<property name="height" direction="asc" />
</datastore-index>
<datastore-index kind="Greeting" ancestor="true" source="manual">
<property name="date" direction="asc" />
</datastore-index>
</datastore-indexes>
现在,让我们看看过滤器。 它是一个有效过滤器 - 他只在一个属性上运行(birthYear属性)。
Filter birthYearMinFilter =
new FilterPredicate("birthYear",
FilterOperator.GREATER_THAN_OR_EQUAL,
minBirthYear);
Filter birthYearMaxFilter =
new FilterPredicate("birthYear",
FilterOperator.LESS_THAN_OR_EQUAL,
maxBirthYear);
Filter birthYearRangeFilter =
CompositeFilterOperator.and(birthYearMinFilter, birthYearMaxFilter);
Query q = new Query("Person").setFilter(birthYearRangeFilter);
它是无效过滤器,他在2个属性(birthYear和height)上运行:
Filter birthYearMinFilter =
new FilterPredicate("birthYear",
FilterOperator.GREATER_THAN_OR_EQUAL,
minBirthYear);
Filter heightMaxFilter =
new FilterPredicate("height",
FilterOperator.LESS_THAN_OR_EQUAL,
maxHeight);
Filter invalidFilter =
CompositeFilterOperator.and(birthYearMinFilter, heightMaxFilter);
Query q = new Query("Person").setFilter(invalidFilter);