自适应地构建对象化过滤器

Build up objectify filters adaptively

假设我有多个属性,我可能希望或不希望根据这些属性进行过滤(见下文)。

通过组合五个过滤器调用并添加一个具有五个属性的组合索引,构建一个实际按所有属性过滤的过滤器相当容易。

但是,如果某些属性不需要过滤,我该如何覆盖所有可能的过滤器?

一个选项是为所有可能的组合添加索引,但这很快就会变得难以维护,而且对我来说似乎不是一个有效的解决方案。

我一直在考虑的另一种方法是添加 "dummy" 过滤器,例如设置 kilometersDriven > -1,但是这将排除任何没有值或这些字段具有空值的实体,即也不是我想要的。

在这些情况下建议的做法是什么?

我目前的解决方法是使用 objectify 进行 "basic" 过滤(例如,如果模型始终是必填字段),然后使用 Java 流过滤器进行更复杂的过滤,但是我不确定将永远表现得足够好。

@Entity
public class Car {
    @Id Long id;

    @Index String model;
    @Index String color;
    @Index Boolean hasAC;
    @Index Integer kilometersDriven;
    @Index Date purchaseDate;
}
return objectify.get().load().type(Car.class)
.filter("model", model)
.filter("color", color)
.filter("hasAC", hasAC)
.filter("kilometersDriven", kilometersDriven)
.filter("purchaseDate", purchaseDate)
.list();
<datastore-index kind="Car">
        <property name="model"/>
        <property name="color"/>
        <property name="hasAC"/>
        <property name="kilometersDriven"/>
        <property name="purchaseDate"/>
</datastore-index>

post 在您的应用程序逻辑中处理和过滤额外实体的缺点是延迟和更多的读取操作。但也有逃避不了的时候。

参考下面关于zigzag merge join的内容(app engine的主文章好像不能访问了)

Appengine ZigZag Merge Join Algo

这可以减少仍然为您的过滤器提供灵活性的索引数量。