Solr/Solrj分页

Mik*_*hie 4 java lucene solr solrj

我在我正在创建的Web应用程序中使用solr和solrj来获取索引和搜索功能.我的请求处理程序在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>
Run Code Online (Sandbox Code Playgroud)

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

SolrQuery query = new SolrQuery(searchTerm);
System.out.println(query.getRequestHandler());
System.out.println(query.getRows());
System.out.println(query.getStart());
Run Code Online (Sandbox Code Playgroud)

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

aru*_*run 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);
Run Code Online (Sandbox Code Playgroud)


fre*_*dev 5

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

当您只需要阅读的文档很少时,分页是一件简单的事情,您只需要使用startrows参数.

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

因此,如果你有很多文件,我的意思是数十万甚至数百万,这不是一种可行的方法.
这是可以让你的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;
}
Run Code Online (Sandbox Code Playgroud)