我正在创建的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在他的回答中所说,"客户端不知道你在服务器端设置了什么"。所以不要惊讶它们是空的。另一方面,我要警告您在某些情况下可能出现的分页问题。
分页是一个简单的事情,当你有几个文档要读,所有你要做的是玩start
和rows
参数。
因此,对于每个页面需要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;
}