我需要对Solr(6.6.2)搜索结果进行随机化,但顺序需要与给定的种子一致,这是针对分页搜索,它从一个大得多的结果集中返回有限的结果集,因此,一旦数据被获取,我必须在查询级别而不是应用程序级别进行排序。
最初我尝试了以下方法:
https://localhost:8984/solr/some_index/select?q=*:*&sort=random_999+ASC
其中,999
是在构造查询并将其发送到Solr之前所馈入的常量。该常量值对于每次新的搜索而改变。
这个解决方案是有效的。但是,当我运行查询几次,或者在不同的Solr示例上运行它时,顺序是不同的。
在执行一些阅读之后,random_
通过以下方式生成一个数字:
fieldName.hashCode() + context.docBase + (int)top.getVersion()
这意味着当生成随机数时,它会考虑索引版本。当使用分布式架构或更新索引时,这会成为问题,正如here所解释的那样。
网上有各种推荐的解决方案,但我尽量避免写一个自定义的random
覆盖。是否有某种技巧,我可以在sort
参数中输入某种类型的函数或方程?
例如:min(999,random_999)
尽管这始终会导致相同的顺序,即使其中一个值发生更改。
这个问题有点类似于这个other question,但不完全一样。
我在SO上搜索了包含solr.RandomSortField
的答案,虽然他们指出了问题所在,但没有一个有解决方案。似乎最好的方法是覆盖solr.RandomSortField
逻辑,但不清楚如何覆盖。
前期研究
- https://lucene.472066.n3.nabble.com/Random-sorting-and-result-consistency-across-successive-calls-based-on-seed-td4170508.html
- Solr: Random sort order after index version change
- https://mail-archives.apache.org/mod_mbox/lucene-dev/201811.mbox/%3CJIRA.13196983.1541639245000.300557.1541639520069@Atlassian.JIRA%3E
- Solr - Return random results (Sort by Random)
- https://realize.be/blog/random-results-apache-solr-and-drupal
- https://lucene.472066.n3.nabble.com/Sorting-with-customized-function-of-score-td3987281.html
1条答案
按热度按时间4nkexdtk1#
即使在实现了自定义随机排序字段之后,Solr示例之间的结果仍然不同。
我最终添加了一个在索引时填充的新字段,它是文档中已经存在的ID字段的32位哈希值。
然后,我构建了一个“无状态”线性同余生成器,以生成一组可接受的随机数,用于排序:
rand.Next()
由于该函数在技术上为每一行传递新的种子,并且由于它不存储状态(像
rand.Next()
那样),因此该解决方案不可否认地较差,并且它不是真正的PRNG;然而,它似乎确实让我走了大部分的路。注意,您将不得不根据数据集的大小和hash_int_id
等效字段中的值的大小来调整值。