5

我正在创建的 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>

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

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

三个打印语句均显示为空。我知道这些“获取”中的每一个都有一个对应的“集合”,但我想象它们已经通过 solrconfig.xml 中的响应处理程序进行设置。有人可以给我线索吗?

4

2 回答 2

9

在服务器上执行查询之前,客户端不会知道您在服务器端设置了什么,对吗?因此,它们都为空也就不足为奇了。

要实现分页,您需要来自客户端的两个参数 - 页码和每页的项目数。一旦你得到这两个,你可以在客户端构建你的 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);
于 2013-06-07T20:57:27.963 回答
8

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

当您要阅读的文档很少并且您所要做的就是使用startrows参数时,分页是一件简单的事情。

因此,对于希望每页 50 个结果的客户端,使用 start=0&rows=50 请求第 1 页。第 2 页是 start=50&rows=50,第 3 页是 start=100&rows=50,等等。但是为了让 Solr 知道从任意点 N 开始返回哪 50 个文档,它需要建立一个内部队列,其中包含与查询匹配的前 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;
}
于 2016-06-06T00:12:28.063 回答