Solr / Solrj分页

时间:2013-06-07 20:17:05

标签: java solr lucene solrj

我正在使用solr和solrj来创建我正在创建的Web应用程序中的索引和搜索功能。我的请求处理程序在solrconfig.xml中配置如下:

<requestHandler name="/select" class="solr.SearchHandler">
 <lst name="defaults">
   <str name="echoParams">explicit</str>
   <str name="start">0</str>
   <int name="rows">10</int>
   <str name="defType">edismax</str>
   <str name="qf">
      title^10.0 subtitle^7.0 abstract^5.0 content^1.0 text^1.0
   </str>
   <str name="pf">
      title^10.0 subtitle^7.0 abstract^5.0 content^1.0 text^1.0
   </str>
   <str name="df">text</str>

 </lst>
</requestHandler>

目前,索引和搜索效果很好。但是,我想实现分页。配置文件包含“开始”和“行”数据。但是,在solrj中,当我运行时:

SolrQuery query = new SolrQuery(searchTerm);
System.out.println(query.getRequestHandler());
System.out.println(query.getRows());
System.out.println(query.getStart());

三个打印语句均显示为null。我理解每个'gets'都有一个对应的'set',但我想象它们已经通过solrconfig.xml中的响应处理程序设置了。有人能告诉我吗?

2 个答案:

答案 0 :(得分:7)

在服务器上执行查询之前,客户端不知道你在服务器端设置了什么,对吧?因此,它们都是空的并不奇怪。

要实现分页,您需要客户端的两个参数 - 页码和每页的项目数。一旦你得到这两个,你可以在客户端构建你的SolrQuery,如下所示:

SolrQuery query = new SolrQuery(searchTerm);
query.setStart((pageNum - 1) * numItemsPerPage);
query.setRows(numItemsPerPage);
// execute the query on the server and get results
QueryResponse res = solrServer.query(solrQuery);

答案 1 :(得分:5)

正如@arun在他的回答中所说,“客户端不知道你在服务器端设置了什么”。所以不要惊讶他们是空的。另一方面,我会警告你在某些情况下可能出现的分页问题。

当您阅读的文档很少时,分页很简单,您只需使用startrows参数即可。

  

因此,对于每页需要50个结果的客户端,请求页面#1   使用start = 0&amp; rows = 50。页面#2是start = 50&amp; rows = 50,page#3是   start = 100&amp; rows = 50等等。但为了让Solr知道哪50个文档   要从任意点N开始返回,需要建立一个   第一个N + 50个排序文档的内部队列与查询匹配,   这样它就可以扔掉前N个文档,并返回   剩余50.这意味着返回所需的内存量   分页结果随着起始参数的增加而线性增长。

因此,如果你有很多文件,我的意思是数十万甚至数百万,这不是一种可行的方法。
这是可以让你的solr服务器瘫痪的事情。

  

对于向人类用户显示搜索结果的典型应用程序,   由于大多数用户不关心,这往往不是什么大问题   关于浏览搜索结果的第一页    - 但对于想要处理所有数据的自动化系统   与查询匹配的文档,可能会非常令人望而却步。

这意味着如果您有一个网站并且正在分页搜索结果,那么真正的用户就不会那么进一步,但另一方面考虑如果蜘蛛或刮刀试图读取所有网站页面会发生什么。现在我们谈论的是 Deep Paging

我建议阅读这篇惊人的文章:

https://lucidworks.com/blog/2013/12/12/coming-soon-to-solr-efficient-cursor-based-iteration-of-large-result-sets/

并查看此文档页面:

https://cwiki.apache.org/confluence/display/solr/Pagination+of+Results

这是一个尝试解释如何使用游标进行分页的示例。

SolrQuery solrQuery = new SolrQuery();
solrQuery.setRows(500);
solrQuery.setQuery("*:*");
solrQuery.addSort("id", ORDER.asc);  // Pay attention to this line
String cursorMark = CursorMarkParams.CURSOR_MARK_START;
boolean done = false;
while (!done) {
    solrQuery.set(CursorMarkParams.CURSOR_MARK_PARAM, cursorMark);
    QueryResponse rsp = solrClient.query(solrQuery);
    String nextCursorMark = rsp.getNextCursorMark();
    for (SolrDocument d : rsp.getResults()) {
            ... 
    }
    if (cursorMark.equals(nextCursorMark)) {
        done = true;
    }
    cursorMark = nextCursorMark;
}