2011-10-31 28 views
3

我已经在我的Java AppEngine应用程式配置Appstats会,发现一个JDO查询返回在一个单独的RunQuery RPC调用的查询检索每个对象的几个对象的结果。如何防止单个JDO查询执行多个RPC RunQuery调用execute()?

不应该查询在一个RPC调用来完成?

我试过配置Fetchgroups和Fetchplans要尽量避免这一点,但无济于事。

我的代码是这样的:

Query query = pm.newQuery(WidgetDSO.class); 

String filter = "widgetId == param1 || widgetId == param2 || widgetId == param3"; 
String parameters = "String param1, String param2, String param3"; 

query.setFilter(filter.toString()); 
query.declareParameters(parameters.toString()); 

List<WidgetDSO> results = (List<WidgetDSO>) query.executeWithArray(widgetIds); 
if (!results.isEmpty()) 
... 

在运行此,将Appstats告诉我,最后一行results.isEmpty()结果尽可能多的RPC调用为对象检索:

@104ms datastore_v3.RunQuery real=5ms api=21ms 
@422ms datastore_v3.RunQuery real=4ms api=12ms 
@428ms datastore_v3.RunQuery real=4ms api=12ms 
@434ms datastore_v3.RunQuery real=3ms api=12ms 
@439ms datastore_v3.RunQuery real=4ms api=12ms 
@445ms datastore_v3.RunQuery real=4ms api=12ms 
@451ms datastore_v3.RunQuery real=4ms api=21ms 
@463ms datastore_v3.RunQuery real=5ms api=21ms 

堆栈跟踪对于每个这些调用是相同的(只是部分堆栈跟踪):

com.google.appengine.tools.appstats.Recorder:290 makeAsyncCall() 
com.google.apphosting.api.ApiProxy:184 makeAsyncCall() 
com.google.appengine.api.datastore.DatastoreApiHelper:81 makeAsyncCall() 
com.google.appengine.api.datastore.PreparedQueryImpl:144 runQuery() 
com.google.appengine.api.datastore.PreparedQueryImpl:70 asIterator() 
com.google.appengine.api.datastore.PreparedMultiQuery$FilteredMultiQueryIterator:165 getNextIterator() 
com.google.appengine.api.datastore.PreparedMultiQuery$FilteredMultiQueryIterator:184 computeNext() 
com.google.appengine.api.datastore.PreparedMultiQuery$FilteredMultiQueryIterator:98 computeNext() 
com.google.appengine.api.datastore.AbstractIterator:52 tryToComputeNext() 
com.google.appengine.api.datastore.AbstractIterator:47 hasNext() 
com.google.appengine.api.datastore.BasePreparedQuery$UncompilablePreparedQuery$1:86 hasNext() 
org.datanucleus.store.appengine.query.RuntimeExceptionWrappingIterator$1:50 get() 
org.datanucleus.store.appengine.query.RuntimeExceptionWrappingIterator$1:46 get() 
org.datanucleus.store.appengine.query.QueryExceptionWrappers$1:51 get() 
org.datanucleus.store.appengine.query.QueryExceptionWrappers$2:86 get() 
org.datanucleus.store.appengine.query.RuntimeExceptionWrappingIterator:105 hasNext() 
org.datanucleus.store.appengine.query.LazyResult:115 resolveAll() 
org.datanucleus.store.appengine.query.LazyResult:110 size() 
org.datanucleus.store.appengine.query.StreamingQueryResult:130 size() 
org.datanucleus.store.query.AbstractQueryResult:312 isEmpty() 
org.instantplaces.im.server.dso.WidgetDSO:209 getWidgetsFromDSO() 
org.instantplaces.im.server.resource.WidgetResource:239 doDelete() 
org.instantplaces.im.server.resource.GenericResource:244 delete() 

有没有办法在一次调用中获取所有对象?

回答

2

那是你确切的代码?如果是这样,我希望至少有3个查询,最低限度。没有原生的“||” (“OR”)查询在数据存储中。 JDO被迫将你的查询翻译成每个选项的一个查询。欲了解更多信息,请参阅docs和相关blog post。 这不是直接说明 - 你需要将||转换成.contains()和.contains()需要多重获取的事实。

||只在状况合法,其中将其分离的过滤器可以 组合成单个含有()滤波器:

的含有()运算符还执行多个查询,一个用于在每个项目提供的列表值,其中所有其他过滤器都相同,并且contains()过滤器被替换为等于过滤器。