假设我有一个简单的实体层次结构设置,其中基类(抽象)类具有公共字段:
@Entity
public abstract class Base {
@Id
Long mId;
@Index
Long mVal;
}
现在我有了一个子类(Java和Objectify):
@Subclass(index=true)
public class Concrete extends Base {
@Index mOtherVal;
}
保存Concrete
后,它会在数据存储区中为所有字段(mId
,mVal
和mOtherVal
)正确创建条目。但是,如果我尝试使用Concrete
上的过滤器对mVal
条目运行查询,则应用引擎抱怨没有索引:
List<Concrete> result =
OfyService.ofy().load().type(Concrete.class).filter("mVal > ", 10).list();
我看到这样的异常日志:
com.google.api.server.spi.SystemService invokeServiceMethod: cause={0}
com.google.appengine.api.datastore.DatastoreNeedIndexException: no matching index found.
The suggested index for this query is:
<datastore-index kind="Post" ancestor="false" source="manual">
<property name="^i" direction="asc"/>
<property name="mVal" direction="asc"/>
</datastore-index>
我没有故意创建datastore-indexes.xml
,因为Objectify文档声明字段上的索引是动态创建的。所以我的问题是:这是Objectify的已知限制,还是我做错了什么?
答案 0 :(得分:1)
正如您可能从问题的评论中找到的那样,您需要datastore-indexes.xml
中的多属性索引。
我希望很明显为什么这是必要的 - 你要求查询mVal
受到不等式和鉴别器索引的约束(由Objectify作为属性^i
实现)包括特定值。如果你想要更聪明一点,你可以查询ofy().load().type(Base.class).filter("mVal > ", 10)
并且你不会需要额外的索引,因为简单的单属性索引就足够了。
多属性索引(由GAE在datastore-indexes.xml中维护)与Objectify维护的单个属性索引非常不同。这在GAE文档中详细解释。