如何使用Solr管理“分页”?

我有一个分类广告网站…我让Solr搜索分类广告,然后返回ID:nrs然后我用它来放入一个数组。 然后我使用这个数组在MySql db中查找任何分类,其中ID:s匹配Solr返回的数组中的ID:s。

现在,因为这个数组可能非常大(100个记录或更多),所以我需要“页面”结果,这样一次可能返回100个。 然后在MySql中使用这100个ID:s来查找分类。

那么,是否可以使用SOLR进行寻呼?

如果是这样,怎么样? 我需要示例代码……结果会是什么样的。

我大多需要一个彻底的例子!

谢谢

看看IBM 。 也许这会让你走上正确的道路。

结果数:指定要返回的最大结果数。

开始:结果集中开始的偏移量。 这对于分页很有用。

所以你可能想要一些变化

10 0 

您的solr客户端应该提供一些方法来获得结果总数而不会有太多麻烦。

使用start和rows参数管理分页,例如:

 ?q=something&rows=10&start=20 

从文件20开始,将为您提供10份文件。

关于从MySQL获取其他信息,您可以自己动手。 我和其他人已经建议你将所有内容存储在Solr中,以避免对MySQL进行额外的查询。

可能有点老问题和许多有用的答案和建议,但我会尝试总结结果并描述使用游标分页大数据集的解决方案。 我最近遇到了这个问题。

正如Yonik所提到的 ,通常的start / rows的问题是,当我们有大数据集并且start比零更远( 更远 )时,我们在效率和内存方面有很好的开销。 这是因为从500K记录的“中间”获取20个文档+使用排序,至少需要对所有数据集进行排序(内部唯一的排序 )。 此外,如果搜索是分发的,那将更加消耗资源。 应将每个分片的数据集( 500 020行 )返回到要合并的聚合器节点,以找出适用的20行。

Solr无法首先确定哪个匹配文档是排序顺序的999001st结果,而不首先确定第一个999000匹配排序结果是什么。


这里的解决方案是使用Solr cursorMark

在第一个查询中,您宣布&cursorMark=* 。 这意味着下一个:

你可以认为这类似于start=0作为告诉Solr“ 从我的排序结果的开始处开始 ”的一种方式,除了它还告诉Solr你想要使用Cursor。

这里的一个“警告”是你的sort子句必须包含uniqueKey字段。 如果它是唯一的,它可以是id字段。

第一个查询的一部分将如下所示:

 ?sort=price desc,id asc&start=0&cursorMark=* ... 

结果您将收到下一个结构

 { "response":{"numFound":20,"start":0,"docs":[ /* docs here */ ]}, "nextCursorMark":"AoIIRPoAAFBX" // Here is cursor mark for next "page" } 

要检索下一页,下一个查询将显示下一个:

 ?sort=price desc,id asc&start=0&cursorMark=AoIIRPoAAFBX ... 

注意前一个响应的cursorMark 。 结果,您将获得下一页结果( 与第一个响应相同的结构,但具有另一个nextCursorMarker )。 等等 …

这种方法理想地适用于无限滚动分页,但要在经典分页中使用它,有一些事情要考虑:)。

这里有一些我发现解决这个问题的参考资料,希望它能帮助别人完成它。

  • 分页结果
  • Solr中的排序,分页和深度分页 ( Yonik的材料)(非常感谢!
  • 基于高效游标的大结果集迭代

“start”参数控制搜索结果的偏移量,“rows”参数控制从那里返回的文档数。

如果您正在进行“深度分页”(迭代多页),那么使用游标迭代结果集可以获得更好的性能。

我认为值得一提的是,solr与当前页面一起返回的结果是找到的记录总数。

例如调用:

 http://192.168.0.1:8983/solr/select?qt=edismax&fl=*,score&qf=content^2%20metatag.description^3%20title^5%20metatag.keywords^10&q=something&start=20&rows=10&wt=xml&version=2.2 

回应是:

   0 1  *,score something content^2 metatag.description^3 title^5 metatag.keywords^10 edismax xml 10 2.2    ... ... ... ... 

使用solrj,方法查询返回一个SolrDocumentList,它具有以下方法:getNumFound()。