按常数排序
Sort by constant number
我需要随机化 Solr (6.6.2) 搜索结果,但给定特定种子的顺序需要保持一致。这是一个分页搜索,returns 来自一个更大的结果集的有限结果集,所以我必须在查询级别而不是在获取数据后在应用程序级别进行排序。
最初我试过这个:
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,但又不完全。
我在包含 solr.RandomSortField
的 SO 上搜索了答案,虽然他们指出了问题所在,但其中 none 有解决方案。似乎最好的方法是覆盖 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
即使在实现了自定义随机排序字段之后,不同 Solr 实例的结果仍然不同。
我最终添加了一个在索引时填充的新字段,它是文档中已存在的 ID 字段的 32 位散列。
然后我构建了一个“无状态”线性同余生成器来生成一组可接受的随机数以用于排序:
?sort=mod(product(hash_int_id,{seedConstant},982451653), 104395301) asc
由于这个函数在技术上为每一行传递一个新的种子,并且因为它不存储状态(就像 rand.Next()
那样),所以这个解决方案是公认的劣质并且它不是真正的 PRNG;但是,它似乎确实让我完成了大部分工作。请注意,您必须根据数据集的大小和 hash_int_id
等效字段中值的大小调整您的值。
我需要随机化 Solr (6.6.2) 搜索结果,但给定特定种子的顺序需要保持一致。这是一个分页搜索,returns 来自一个更大的结果集的有限结果集,所以我必须在查询级别而不是在获取数据后在应用程序级别进行排序。
最初我试过这个:
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,但又不完全。
我在包含 solr.RandomSortField
的 SO 上搜索了答案,虽然他们指出了问题所在,但其中 none 有解决方案。似乎最好的方法是覆盖 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
即使在实现了自定义随机排序字段之后,不同 Solr 实例的结果仍然不同。
我最终添加了一个在索引时填充的新字段,它是文档中已存在的 ID 字段的 32 位散列。
然后我构建了一个“无状态”线性同余生成器来生成一组可接受的随机数以用于排序:
?sort=mod(product(hash_int_id,{seedConstant},982451653), 104395301) asc
由于这个函数在技术上为每一行传递一个新的种子,并且因为它不存储状态(就像 rand.Next()
那样),所以这个解决方案是公认的劣质并且它不是真正的 PRNG;但是,它似乎确实让我完成了大部分工作。请注意,您必须根据数据集的大小和 hash_int_id
等效字段中值的大小调整您的值。