我正在使用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中的响应处理程序设置了。有人能告诉我吗?
答案 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在他的回答中所说,“客户端不知道你在服务器端设置了什么”。所以不要惊讶他们是空的。另一方面,我会警告你在某些情况下可能出现的分页问题。
当您阅读的文档很少时,分页很简单,您只需使用start
和rows
参数即可。
因此,对于每页需要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://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;
}