使用 order() 的 GAE 和 Objectify 查询和错误
GAE and Objectify query and error using order()
我正在处理一个演示项目,其中一种方法提供了对类型的基本查询。
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.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.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.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
该错误基本上告诉了您需要知道的一切。您应该添加:
<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.
在这些属性上有单独的索引并不重要。您需要为此查询创建复合索引(如错误消息中所述)。
您的应用需要为有序查询定义不同的索引。还需要 direction
。看
How to fix index error when querying GAE datastore?
通常情况下,devserver 能够根据本地应用程序实际执行的查询自动 generate/update 本地开发环境中的索引。但是您需要手动将更新后的索引文件上传到 GAE(并确保索引已完成),然后您的 GAE 应用才能实际使用它。
如果开发服务器无法自动 generate/update 索引文件,您仍然可以手动完成。
我正在处理一个演示项目,其中一种方法提供了对类型的基本查询。
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.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.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.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
该错误基本上告诉了您需要知道的一切。您应该添加:
<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.
在这些属性上有单独的索引并不重要。您需要为此查询创建复合索引(如错误消息中所述)。
您的应用需要为有序查询定义不同的索引。还需要 direction
。看
How to fix index error when querying GAE datastore?
通常情况下,devserver 能够根据本地应用程序实际执行的查询自动 generate/update 本地开发环境中的索引。但是您需要手动将更新后的索引文件上传到 GAE(并确保索引已完成),然后您的 GAE 应用才能实际使用它。
如果开发服务器无法自动 generate/update 索引文件,您仍然可以手动完成。