雄辩 - 有偏见的随机选择记录

时间:2016-05-01 15:32:36

标签: laravel laravel-5 eloquent laravel-5.2

我有一个模型Quote,它有两个属性: quote probability 。我想选择随机引用,但必须更频繁地选择概率较高的引号。例如,如果我们有

$q1->probability == 0.15

$q2->probability == 0.75

后者必须选择的可能性<5> 。以下命令进行随机引用选择:

$quote = Quote::orderByRaw('RAND()')->first();

但我需要选择有偏见,如上所述。怎么做到这一点?

1 个答案:

答案 0 :(得分:3)

我不确定是否有办法用MySQL做到这一点,但这个问题已在PHP之前提出并解决过:Generating random results by weight in PHP?

基本上,您需要提取引用ID和权重([ id => 1, weight => 0.5])以及所有权重的总和(示例中为0.90)。然后,没有特定的顺序,循环遍历数组并减去每个权重。

因此,如果我有一个包含这些值的MySQL表,

[
    [ 'id' => 1, weight => 1 ],
    [ 'id' => 2, weight => 2 ],
    [ 'id' => 3, weight => 4 ],
]

然后,您将在07之间生成一个数字,因为这是所有权重的总和。此时,您将获取每个项目并从随机数中减去它。一个例子看起来像这样。

$quoteWeights = Quote::select('id', 'weight')->get();
$weightSum    = $quoteWeights->sum('weight');
$weightRand   = mt_rand(0, $weightSum);

foreach ($quoteWeights as $quoteWeight)
{
    // Subtract our weight from the rand.
    $weightRand -= $quoteWeight->weight;

    // If it's bust, we want to return the winning model.
    if ($weightRand <= 0)
    {
        // Refresh the model so we get all attributes.
        return $quoteWeight->fresh();
    }
}

这是未经测试的代码,但我打赌它正确运行。

如果你有一个高负载服务器或一个巨大的报价数据库,你可能想要在第一部分调用缓存。