2016-05-01 50 views
1

我有一个模型Quote,它有两个属性:报价概率。我想选择一个随机报价,但必须更频繁地选择具有较高概率的报价。例如,如果我们有雄辩 - 随机选择一个记录

$q1->probability == 0.15 

$q2->probability == 0.75 

后者必须5倍,可能被选择。下面的命令使随机报价选择:

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

但我需要选择要,因为它是上面提到的。如何实现这一目标?

回答

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(); 
    } 
} 

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

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

+0

感谢您的回答。好的技术 –