Sphinx Mulit-Level Sort with Randomize

时间:2018-03-07 12:56:53

标签: sphinx

以下是我对Sphinx Sort的挑战,其中有供应商支付高级展示位置的供应商以及不支持高级展示位置的供应商:

我已经做了多级订单,包括PaidVendorStatus,其中0或1为:

order by PaidVendorStatus,Weight()

所以从本质上讲,我最终得到了多个排序组​​:

  • PaidVendorStatus = 1,Weight1
  • ....
  • PaidVendorStatus = 1,WeightN
  • PaidVendorStatus = 0,Weight1
  • ...
  • PaidVendorStatus = 0,WeightN

问题是我有三个目标:

  1. 随机优先排序任何给定排序组中的每个供应商
  2. 让每个供应商的随机分配顶级位置的'赔率'无论他们在组中返回多少记录都是相同的(因此,如果供应商A有50个结果而VendorB有2个结果,他们仍然有50%的可能性随机分配任何给定的地点)
  3. 理想情况下,在任何给定的搜索中保持相同的结果顺序(这样,如果用户再次搜索,则会显示相同的顺序
  4. 我尝试了各种解决方案:

    Select CRC32(Vendor) as RANDOM...Order by PaidVendorStatus,Weight(),RANDOM

    解决了23,除了由于CRC32的性质总是将同一个供应商放在第一位(以及第二位,第三位等),所以本质上并不能解决问题一点都不。

    我尝试在我的sphinx sql_attr_string Sphinx Configuration中创建一个concatenation供应商和记录标题(Select... concat(Vendor,Title) as RANDOMIZER ..)`然后用它来随机化< / p>

    Select CRC32(RANDOMIZER) as RANDOM...

    解决了13现在Title字段被随机化错误抛出,因此相同的供应商并不总是获得第一次结算。但是,它在2处失败,因为实质上我只按标题排序,因此供应商B有两个结果,现在排序的变化非常小。

    在一个理想的世界中,我自然可以这样订购;

    Order by PaidVendorStatus,Weight(),RAND(Vendor)

    但这是不可能的。

    对此的任何想法都表示赞赏。我按照Barry Hunter的建议this thread on UDF检查了btw,但除非我根本不理解它(可能),否则它似乎不是解决这个问题的方法。

2 个答案:

答案 0 :(得分:0)

一个好主意是:

SELECT * FROM (
  SELECT *,uniqueserial(vendor_id) AS sorter FROM index WHERE MATCH(...) 
       ORDER BY PaidVendorStatus DESC ,Weight() DESC LIMIT 1000
) ORDER BY sorter DESC, WEIGHT() DESC:

利用pysudeo子查询利用SPhixnes的“多重排序”功能。

由于内部查询首先由PaidVendor排序,因此它的项目是拳头,因此这种情况很糟糕。这会影响调用unqique序列的ordr。

它并非真正“随机化”结果,似乎你将它们随机化以混淆供应商(因此单个供应商不会产生结果.Bisseseserial通过“传播”特定供应商的结果 - 结果将倾向于通过供应商循环。

这很棘手,因为它利用了相对无证的sphinx特征 - 子查询。

对于UDF,请参阅http://svn.geograph.org.uk/svn/modules/trunk/sphinx/

答案 1 :(得分:0)

仍然没有对你的偏见随机答案(如2.)

但只记得另一个功能可以帮助3. - 可以为随机数提供特定的种子。通常,随机生成器从当前时间播种,这会产生不断变化的值,但使用特定的种子。

然而,种子是一个数字,所以需要一个可预测但却在变化的数字。 CRC可以查询吗?

... sphinx不支持OPTION中的表达式,因此必须计算应用程序中的哈希值。

<?php

$query = $db->Quote($_GET['q']);
$crc = crc32($query);

$sql = "SELECT id,IDIV(WEIGHT(),100) as i,RAND() as r FROM index WHERE MATCH($query) 
             ORDER BY PaidVendorStatus DESC,i DESC,r ASC OPTION random_seed=$crc";

如果希望结果只是缓慢发展,请添加当前日期,以便每天都是新选择......

 $crc = crc32($query.date('Ymd'));