需要在ElasticSearch中找到一种方法,以根据字段的特定值提高文档的相关性。具体来说,我的所有文档中都有一个特殊字段,字段值越高,包含它的文档就越相关,无论搜索是什么。
考虑以下文档结构:
{
"_all" : {"enabled" : "true"},
"properties" : {
"_id": {"type" : "string", "store" : "yes", "index" : "not_analyzed"},
"first_name": {"type" : "string", "store" : "yes", "index" : "yes"},
"last_name": {"type" : "string", "store" : "yes", "index" : "yes"},
"boosting_field": {"type" : "integer", "store" : "yes", "index" : "yes"}
}
}
我希望具有较高的boosting_field值的文档与具有较低的boosting_field值的文档相比,本质上更相关。这只是一个起点 - 在确定搜索中每个文档的最终相关性得分时,还将考虑查询与其他字段之间的匹配。但是,其他条件相同,提升字段越高,文档越相关。
任何人都知道如何做到这一点?
非常感谢!
答案 0 :(得分:68)
您可以在索引时或查询时提升。我通常更喜欢查询时间提升,即使它使查询稍慢,否则我每次想要改变我的提升因素时都需要重新索引,这通常需要微调并且需要非常灵活。
使用elasticsearch查询DSL有不同的方法来应用查询时间提升:
如果要对匹配特定查询或过滤器的文档进行特定提升,前三个查询很有用。例如,如果您只想提升上个月发布的文档。你可以在你的boosting_field中使用这种方法,但是你需要手动定义一些boosting_field间隔并给它们一个不同的提升,这不是那么好。
最好的解决方案是使用Custom Score Query,它允许您使用脚本进行查询并自定义其得分。它非常强大,使用脚本可以直接修改乐谱本身。首先,我将boosting_field值缩放到0到1之间的值,这样你的最终得分就不会变成一个大数字。为此,您需要预测字段可以包含的最小值和最大值。比如说最小0和最大100000。如果将boosting_field值缩放为0到1之间的数字,则可以将结果添加到实际分数中,如下所示:
{
"query" : {
"custom_score" : {
"query" : {
"match_all" : {}
},
"script" : "_score + (1 * doc.boosting_field.doubleValue / 100000)"
}
}
}
您还可以考虑使用boosting_field作为提升因子(_score *
而不是_score +
),但是您需要将其缩放到最小值为1的区间(只需添加一个+1)。
您甚至可以调整结果,以便更改其重要性,为您用来影响分数的值添加权重。如果您需要将多个增强因子组合在一起以便给予它们不同的重量,您将需要更多。
答案 1 :(得分:13)
使用最新版本的Elasticsearch(版本1.3+),您将要使用"功能得分查询":
得分的query_string搜索如下所示:
{
'query': {
'function_score': {
'query': { 'query_string': { 'query': 'my search terms' } },
'functions': [{ 'field_value_factor': { 'field': 'my_boost' } }]
}
}
}
" my_boost"是搜索索引中的数字字段,其中包含单个文档的提升因子。可能看起来像这样:
{ "my_boost": { "type": "float", "index": "not_analyzed" } }
答案 2 :(得分:3)
如果你想避免每次在查询中进行提升,你可以考虑将它添加到你的映射中直接添加“boost:factor。
因此,您的映射可能如下所示:
{
"_all" : {"enabled" : "true"},
"properties" : {
"_id": {"type" : "string", "store" : "yes", "index" : "not_analyzed"},
"first_name": {"type" : "string", "store" : "yes", "index" : "yes"},
"last_name": {"type" : "string", "store" : "yes", "index" : "yes"},
"boosting_field": {"type" : "integer", "store" : "yes", "index" : "yes", "boost" : 10.0,}
}
}
答案 3 :(得分:0)
如果您使用的是Nest,则应使用以下语法:
.Query(q => q
.Bool(b => b
.Should(s => s
.FunctionScore(fs => fs
.Functions(fn => fn
.FieldValueFactor(fvf => fvf
.Field(f => f.Significance)
.Weight(2)
.Missing(1)
))))
.Must(m => m
.Match(ma => ma
.Field(f => f.MySearchData)
.Query(query)
))))