Solr/Solrj pagination



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

目前,索引和搜索工作得很好。但是,我想实现分页。配置文件包含"start"one_answers"row"数据。然而,在solrj中,当我运行:

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

三个print语句都显示为null。我理解这些"get"中的每一个都有一个对应的"set",但我本以为它们已经通过solrconfig.xml中的响应处理程序设置好了。有人能给我提示一下吗?

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

要实现分页,您需要来自客户端的两个参数—页码和每页的条目数。一旦获得了这两个,就可以在客户端构造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);

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

分页是一个简单的事情,当你有几个文档要读,所有你要做的是玩startrows参数。

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

所以如果你有很多文件,我的意思是数十万甚至数百万,这不是一个可行的方法。
这类事情可能会让您的solr服务器崩溃。

对于向人类用户显示搜索结果的典型应用程序,这并不是什么大问题,因为大多数用户并不在意关于深入挖掘搜索结果的前几页——但对于那些想要处理所有数据的自动化系统来说匹配查询的文档,这可能是严重禁止的。

这意味着,如果你有一个网站,并分页搜索结果,一个真正的用户不会走得那么远,但考虑到另一方面,如果蜘蛛或刮板试图阅读所有的网站页面会发生什么。现在我们讨论的是深度分页

我建议你读这篇很棒的文章:

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 +的+结果

这里有一个例子,试图解释如何使用游标分页。

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;
}

最新更新