App Engine的全文搜索API(Java) [英] Full Text Search API for App Engine (Java)

查看:119
本文介绍了App Engine的全文搜索API(Java)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试使用Google AppEngine的实验性搜索API。我正在使用SDK 1.6.6。
到目前为止,我可以将条目添加到索引并在我的开发环境中进行搜索。
当我部署我的应用程序时,我仍然可以向索引添加条目,但是当我尝试
执行搜索时,我会得到以下异常日志:

I have been trying to use the experimental Search API for the Google AppEngine. I am using SDK 1.6.6. So far, I could add entries to an index and search it in my development environment. When I deploy my application, I can still add entries to the index, but when I try to perform a search, I get the following exception log:

br.com.qmagico.server.service.search.GenericSearchService search: Busca com query 'soma' falhou
com.google.appengine.api.search.SearchException: 
at com.google.appengine.api.search.IndexImpl$3.convertException(IndexImpl.java:268)
at com.google.appengine.api.utils.FutureWrapper.get(FutureWrapper.java:106)
at com.google.appengine.api.search.FutureHelper.getInternal(FutureHelper.java:74)
at com.google.appengine.api.search.FutureHelper.quietGet(FutureHelper.java:33)
at com.google.appengine.api.search.IndexImpl.search(IndexImpl.java:390)
at br.com.qmagico.server.service.search.GenericSearchService.search(GenericSearchService.java:109)
at br.com.qmagico.server.service.search.AulaSearchService.search(AulaSearchService.java:50)
at br.com.qmagico.server.handler.GetAulasHandler.executeLoggedException(GetAulasHandler.java:45)
at br.com.qmagico.server.handler.GetAulasHandler.executeLoggedException(GetAulasHandler.java:1)
at br.com.qmagico.server.QmActionHandler.execute(QmActionHandler.java:23)
at com.gwtplatform.dispatch.server.AbstractDispatchImpl.doExecute(AbstractDispatchImpl.java:153)
at com.gwtplatform.dispatch.server.AbstractDispatchImpl.execute(AbstractDispatchImpl.java:111)
at com.gwtplatform.dispatch.server.AbstractDispatchServiceImpl.execute(AbstractDispatchServiceImpl.java:81)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
at com.google.apphosting.runtime.security.shared.intercept.java.lang.reflect.Method_$1.run(Method_.java:165)
at java.security.AccessController.doPrivileged(Native Method)
at com.google.apphosting.runtime.security.shared.intercept.java.lang.reflect.Method_.privilegedInvoke(Method_.java:163)
at com.google.apphosting.runtime.security.shared.intercept.java.lang.reflect.Method_.invoke_(Method_.java:124)
at com.google.apphosting.runtime.security.shared.intercept.java.lang.reflect.Method_.invoke(Method_.java:43)
at com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:569)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceServlet.java:208)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.processPost(RemoteServiceServlet.java:248)
at com.google.gwt.user.server.rpc.AbstractRemoteServiceServlet.doPost(AbstractRemoteServiceServlet.java:62)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at com.google.inject.servlet.ServletDefinition.doService(ServletDefinition.java:263)
at com.google.inject.servlet.ServletDefinition.service(ServletDefinition.java:178)
at com.google.inject.servlet.ManagedServletPipeline.service(ManagedServletPipeline.java:91)
at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:62)
at com.google.inject.servlet.ManagedFilterPipeline.dispatch(ManagedFilterPipeline.java:118)
at com.google.inject.servlet.GuiceFilter.doFilter(GuiceFilter.java:113)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.apphosting.utils.servlet.ParseBlobUploadFilter.doFilter(ParseBlobUploadFilter.java:102)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.apphosting.runtime.jetty.SaveSessionFilter.doFilter(SaveSessionFilter.java:35)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43)
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:249)
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:135)
at com.google.apphosting.runtime.JavaRuntime$RequestRunnable.run(JavaRuntime.java:477)
at com.google.tracing.TraceContext$TraceContextRunnable.runInContext(TraceContext.java:449)
at com.google.tracing.TraceContext$TraceContextRunnable$1.run(TraceContext.java:455)
at com.google.tracing.TraceContext.runInContext(TraceContext.java:695)
at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContextNoUnref(TraceContext.java:333)
at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContext(TraceContext.java:325)
at com.google.tracing.TraceContext$TraceContextRunnable.run(TraceContext.java:453)
at com.google.apphosting.runtime.ThreadGroupPool$PoolEntry.run(ThreadGroupPool.java:251)
at java.lang.Thread.run(Thread.java:679)

执行此搜索的代码片段是这样的:

The piece of code performing this search is this one:

public List<Long> search(Index index, String queryStr, String sortField) {
    ArrayList<Long> ids = new ArrayList<Long>();
    if (queryStr != null && !queryStr.isEmpty()) {
        int limit = 5;
        try {
            QueryOptions.Builder builder = QueryOptions.newBuilder().setLimit(limit);
            if (sortField != null) {
                builder = builder.setSortOptions(SortOptions.newBuilder()
                    .addSortExpression(SortExpression.newBuilder()
                        .setExpression(sortField)
                        .setDefaultValue("")
                        .setDirection(SortExpression.SortDirection.DESCENDING))
                    .build());
            }
            QueryOptions queryOptions = builder.build();

            Query query = Query.newBuilder()
                .setOptions(queryOptions)
                .build(queryStr);
            LOG.info("Enviando query " + query);
            Results<ScoredDocument> results = index.search(query);
            for (ScoredDocument scoredDoc : results) {
                ids.add(scoredDoc.getOnlyField("id").getNumber().longValue());
            }
        } catch (RuntimeException e) {
            LOG.log(Level.SEVERE, "Busca com query '" + queryStr + "' falhou", e);
        }
    }
    return ids;
}

有没有人会为我解决这个问题?

Does anyone one what I should do to fix this?

Thx!

推荐答案

您可能希望查看使用文档等级在索引中预设文档。文档上的排名字段默认设置为自2011年1月1日以来的秒数。但是,您可以提供整数排名值。例如,如果您想按价格对产品目录进行分类(从低到高,从高到低)。

If you think sorting is your issue then you may want to look at presorting your documents in the index using Document rank. The rank field on documents is by default set to the number of seconds since Jan 1 2011. However, you can supply a integer rank value. For example, if you wanted to sort a product catalog on price (low to high, and high to low). The rank is used to presort the documents in the index.

public Index getIndex(String indexName) {
    IndexSpec indexSpec = IndexSpec.newBuilder().setName(indexName).build();
    return SearchServiceFactory.getSearchService().getIndex(indexSpec);
}

Document doc = Document.newBuilder()
    .addField(Field.newBuilder().setName('name').setText("some text"))
    .setRank(functionToGetPrice())
    .build();

getIndex("productHighToLow").put(doc);

doc = Document.newBuilder()
    .addField(Field.newBuilder().setName('name').setText("some text"))
    .setRank(MAXINT-functionToGetPrice())
    .build();

getIndex("productLowToHigh").put(doc);

然后,当您搜索您的索引时,如果用户选择了价格从低到高并且查询LED电视,那么你可以简单地发出一个查询,如

Then when you search your index, if the user has selected "price low to high" and queried for "LED TV", then you can simply issue a query like

getIndex("productLowToHigh").search("LED TV");

,即使对于大型(产品目录)索引,它也会更快且语义更正。

and it will be faster and semantically correct even for large (product catalog) indexes.

这篇关于App Engine的全文搜索API(Java)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆