使用order()GAE和Objectify查询和错误

时间:2016-11-17 17:36:35

标签: google-app-engine filter google-cloud-datastore objectify

我正在开发一个Demo项目,其中一个方法提供了一个Type的基本查询。

    public List<Conference> filterPlayground(){

      Query<Conference> query = (ofy().load().type(Conference.class)).order("name");

      query = query.filter("topics =", "Medical Innovations");  
      query = query.filter("city =","London");

      return query.list();
}

我的会议实体拥有名称,城市和主题的@Index。

但是当我在API Explorer中运行该方法时,我得到了一个例外...(见下文)。关于为什么使用order方法的任何快速指针都会导致这种情况。我知道这是订单方法,没有它就没有错误。

Uncaught exception from servlet
java.io.IOException:    com.google.appengine.repackaged.org.codehaus.jackson.map.JsonMappingExcepti on: no matching index found. recommended index is:
- kind: Conference
 properties:
 - name: city
 - name: topics
 - name: name

The suggested index for this query is:
<datastore-index kind="Conference" ancestor="false" source="manual">
<property name="city" direction="asc"/>
<property name="topics" direction="asc"/>
<property name="name" direction="asc"/>
</datastore-index>

(through reference chain: java.util.HashMap["items"])
at com.google.api.server.spi.response.ServletResponseResultWriter.writeValueAs    String(ServletResponseResultWriter.java:187)
at com.google.api.server.spi.response.ServletResponseResultWriter.write(ServletResponseResultWriter.java:74)
at com.google.api.server.spi.SystemService.invokeServiceMethod(SystemService.java:394)
at com.google.api.server.spi.SystemServiceServlet.execute(SystemServiceServlet.java:113)
at com.google.api.server.spi.SystemServiceServlet.doPost(SystemServiceServlet.java:71)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
at com.google.apphosting.utils.servlet.ParseBlobUploadFilter.doFilter(ParseBlobUploadFilter.java:125)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.apphosting.runtime.jetty.SaveSessionFilter.doFilter(SaveSessionFilter.java:37)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.apphosting.utils.servlet.JdbcMySqlConnectionCleanupFilter.doFilter(JdbcMySqlConnectionCleanupFilter.java:60)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:48)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
at     com.google.apphosting.runtime.jetty.AppVersionHandlerMap.handle(AppVersionHandlerMap.java:257)
at     org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:326)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:923)
at com.google.apphosting.runtime.jetty.RpcRequestParser.parseAvailable(RpcRequestParser.java:76)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
at com.google.apphosting.runtime.jetty.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:145)
at com.google.apphosting.runtime.JavaRuntime$RequestRunnable.run(JavaRuntime.java:511)
at com.google.tracing.TraceContext$TraceContextRunnable.runInContext(TraceContext.java:446)
at com.google.tracing.TraceContext$TraceContextRunnable$1.run(TraceContext.java:453)
at com.google.tracing.CurrentContext.runInContext(CurrentContext.java:276)
at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContextNoUnref(TraceContext.java:312)
at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContext(TraceContext.java:304)
at com.google.tracing.TraceContext$TraceContextRunnable.run(TraceContext.java:450)
at com.google.apphosting.runtime.ThreadGroupPool$PoolEntry.run(ThreadGroupPool.java:235)
at java.lang.Thread.run(Thread.java:745)
Caused by:     com.google.appengine.repackaged.org.codehaus.jackson.map.JsonMappingException: no matching index found. recommended index is:
- kind: Conference
  properties:
  - name: city
  - name: topics
  - name: name

The suggested index for this query is:
<datastore-index kind="Conference" ancestor="false" source="manual">
<property name="city" direction="asc"/>
<property name="topics" direction="asc"/>
<property name="name" direction="asc"/>
</datastore-index>

(through reference chain: java.util.HashMap["items"])
at com.google.appengine.repackaged.org.codehaus.jackson.map.JsonMappingException.wrapWithPath(JsonMappingException.java:218)
at com.google.appengine.repackaged.org.codehaus.jackson.map.JsonMappingException.wrapWithPath(JsonMappingException.java:183)
at com.google.appengine.repackaged.org.codehaus.jackson.map.ser.std.SerializerBase.wrapAndThrow(SerializerBase.java:140)
at com.google.appengine.repackaged.org.codehaus.jackson.map.ser.std.MapSerializer.serializeFields(MapSerializer.java:266)
at com.google.appengine.repackaged.org.codehaus.jackson.map.ser.std.MapSerializer.serialize(MapSerializer.java:186)
at com.google.appengine.repackaged.org.codehaus.jackson.map.ser.std.MapSerializer.serialize(MapSerializer.java:23)
at com.google.appengine.repackaged.org.codehaus.jackson.map.ser.StdSerializerProvider._serializeValue(StdSerializerProvider.java:610)
at com.google.appengine.repackaged.org.codehaus.jackson.map.ser.StdSerializerProvider.serializeValue(StdSerializerProvider.java:256)
at com.google.appengine.repackaged.org.codehaus.jackson.map.ObjectWriter._configAndWriteValue(ObjectWriter.java:456)
at com.google.appengine.repackaged.org.codehaus.jackson.map.ObjectWriter.writeValueAsString(ObjectWriter.java:393)
at com.google.api.server.spi.response.ServletResponseResultWriter.writeValueAsString(ServletResponseResultWriter.java:183)
... 38 more

引起:com.google.appengine.api.datastore.DatastoreNeedIndexException:找不到匹配的索引。推荐指数是: - 善良:会议   特性:    - 名称:城市    - 名称:主题    - 姓名:姓名

此查询的建议索引是:                                     

at com.google.appengine.api.datastore.DatastoreApiHelper.translateError(DatastoreApiHelper.java:59)
at com.google.appengine.api.datastore.DatastoreApiHelper$1.convertException(DatastoreApiHelper.java:128)
at com.google.appengine.api.utils.FutureWrapper.get(FutureWrapper.java:97)
at com.google.appengine.api.utils.FutureWrapper.get(FutureWrapper.java:89)
at com.google.appengine.api.datastore.FutureHelper.getInternal(FutureHelper.java:76)
at com.google.appengine.api.datastore.FutureHelper.quietGet(FutureHelper.java:36)
at com.google.appengine.api.datastore.BaseQueryResultsSource.getIndexList(BaseQueryResultsSource.java:159)
at com.google.appengine.api.datastore.BaseQueryResultsSource.loadMoreEntities(BaseQueryResultsSource.java:192)
at com.google.appengine.api.datastore.BaseQueryResultsSource.loadMoreEntities(BaseQueryResultsSource.java:171)
at com.google.appengine.api.datastore.QueryResultIteratorImpl.ensureLoaded(QueryResultIteratorImpl.java:148)
at com.google.appengine.api.datastore.QueryResultIteratorImpl.hasNext(QueryResultIteratorImpl.java:64)
at com.googlecode.objectify.impl.KeysOnlyIterator.hasNext(KeysOnlyIterator.java:29)
at com.googlecode.objectify.impl.ChunkIterator.next(ChunkIterator.java:48)
at com.googlecode.objectify.impl.ChunkIterator.next(ChunkIterator.java:20)
at com.google.common.collect.Iterators$5.hasNext(Iterators.java:597)
at com.google.common.collect.Iterators$PeekingImpl.hasNext(Iterators.java:1216)
at com.googlecode.objectify.impl.ChunkingIterator.hasNext(ChunkingIterator.java:51)
at com.google.common.collect.Lists.newArrayList(Lists.java:144)
at com.google.common.collect.Lists.newArrayList(Lists.java:125)
at com.googlecode.objectify.util.MakeListResult.translate(MakeListResult.java:21)
at com.googlecode.objectify.util.MakeListResult.translate(MakeListResult.java:11)
at com.googlecode.objectify.util.ResultTranslator.nowUncached(ResultTranslator.java:21)
at com.googlecode.objectify.util.ResultCache.now(ResultCache.java:30)
at com.googlecode.objectify.util.ResultProxy.invoke(ResultProxy.java:34)
at com.sun.proxy.$Proxy30.iterator(Unknown Source)
at com.google.appengine.repackaged.org.codehaus.jackson.map.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:45)
at com.google.appengine.repackaged.org.codehaus.jackson.map.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:23)
at com.google.appengine.repackaged.org.codehaus.jackson.map.ser.std.AsArraySerializerBase.serialize(AsArraySerializerBase.java:86)
at com.google.appengine.repackaged.org.codehaus.jackson.map.ser.std.MapSerializer.serializeFields(MapSerializer.java:262)
... 45 more

2 个答案:

答案 0 :(得分:1)

错误基本上告诉你需要知道的一切。你应该添加:

<datastore-index kind="Conference" ancestor="false" source="manual">
<property name="city" direction="asc"/>
<property name="topics" direction="asc"/>
<property name="name" direction="asc"/>
</datastore-index>

index configuration

在这些属性上有单独的索引并不重要。您需要为此查询创建一个复合索引(如错误消息中所述)。

答案 1 :(得分:1)

您的应用需要针对有序查询的不同索引定义。还需要direction。看到 How to fix index error when querying GAE datastore?

通常,devserver能够根据您的本地应用程序实际执行的查询自动生成/更新本地开发环境中的索引。但是,在GAE应用程序实际使用之前,您需要手动将更新的索引文件上传到GAE(并确保索引已完成)。

如果devserver无法自动生成/更新索引文件,您仍然可以手动执行。