我已经运行了一个Rails网站几年了,并且一些文章基于权重字段从数据库中获取。数据结构如下:
{name: 'Content Piece 1', weight: 50}
{name: 'Content Piece 2', weight: 25}
{name: 'Content Piece 3', weight: 25}
我最初编写的 Ruby 代码如下所示:
choices = []
sum = articles.inject(0.0) { |sum, article|
sum += listing['weight']
}
pick = rand(sum)
choices << articles.detect { |listing|
if pick <= listing['weight']
true
else
pick -= listing['weight']
false
end
}
这段代码可以很好地提取每一个内容片段并维护权重。在对数据集运行该代码100次后,多次得到的结果都是根据权重分配得相当平均的内容片段:
100.times do
choices = []
sum = articles.inject(0.0) { |sum, article|
sum += listing['weight']
}
pick = rand(sum)
choices << articles.detect { |listing|
if pick <= listing['weight']
true
else
pick -= listing['weight']
false
end
}
end
{:total_runs=>100, "Content Piece 1"=>51, "Content Piece 2"=>22, "Content Piece 3"=>27}
{:total_runs=>100, "Content Piece 1"=>53, "Content Piece 2"=>30, "Content Piece 3"=>17}
我目前越来越频繁地使用ElasticSearch,希望能够在ES中索引数据,并根据权重提取内容。
我发现了一个非常类似的SO帖子,可以在此处找到:
我已经将搜索查询复制过来,更改为匹配我的数据结构:
{
"sort": ["_score"],
"size": 1,
"query": {
"function_score": {
"functions": [
{
"random_score": {}
},
{
"field_value_factor": {
"field": "weight",
"modifier": "none",
"missing": 0
}
}
],
"score_mode": "multiply",
"boost_mode": "replace"
}
}
}
这个查询确实尊重权重,并且比权重为25的其他两个内容块更多地提取了权重为50的内容块,但它没有将内容分配到总重量为100,如果这样说的话。我运行这个查询100次,结果如下:
{:total_runs=>100, "Content Piece 1"=>70, "Content Piece 2"=>22, "Content Piece 3"=>8}
{:total_runs=>100, "Content Piece 1"=>81, "Content Piece 2"=>7, "Content Piece 3"=>12}
{:total_runs=>100, "Content Piece 1"=>90, "Content Piece 2"=>3, "Content Piece 3"=>7}
由于我对ES还很陌生,仍在学习查询、得分等方面,我想知道是否有人能提供一个解决方案,更好地模拟我编写的Ruby代码,以更有效地根据权重将内容分配到100个部分。 Painless
脚本是否适用于移植Ruby代码?
希望这样说得清楚,如果您有任何疑问,请告诉我,以帮助我解释我要实现的内容。谢谢!
script_score
更新了你的答案,适用于你的情况。 - Pierre-Nicolas Mougel