ElasticSearch——基于字段值提升相关性
Posted
技术标签:
【中文标题】ElasticSearch——基于字段值提升相关性【英文标题】:ElasticSearch -- boosting relevance based on field value 【发布时间】:2012-09-07 18:59:58 【问题描述】:需要在 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 值较低的文档在本质上更相关。这只是一个起点——在确定搜索中每个文档的最终相关性分数时,还将考虑查询与其他字段之间的匹配。但是,在其他条件相同的情况下,提升字段越高,文档的相关性越高。
有人知道怎么做吗?
非常感谢!
【问题讨论】:
另请参阅***.com/a/41813578/5444623,了解按文档类型字段进行的不同提升 【参考方案1】:您可以在索引时或查询时提升。我通常更喜欢查询时间提升,即使它会使查询变慢一点,否则每次我想更改提升因子时都需要重新索引,这通常需要微调并且需要非常灵活。
使用 elasticsearch 查询 DSL 应用查询时间提升的方法有多种:
Boosting Query Custom Filters Score Query Custom Boost Factor Query Custom Score Query如果您想对匹配特定查询或过滤器的文档进行特定提升,前三个查询很有用。例如,如果您只想提升上个月发布的文档。您可以将这种方法与您的 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)。
您甚至可以调整结果以改变其重要性,为您用来影响分数的值添加权重。如果您需要将多个增强因子组合在一起以赋予它们不同的权重,您将更需要这个。
【讨论】:
你能在custom_score中容纳和过滤吗?现在你的查询只有match_all,你能在里面添加一些过滤吗? 您可以使用 filtered query 并向其添加查询和过滤器。 但这无济于事。您在示例中编写的内容对我来说很好,但需要在主查询中添加一个过滤器。, "filter": "and": [ "query": "match": "xxxx": "query": "barfoo" ] 没错,现在只有一个查询来统治所有这些:function_score 查询。【参考方案2】:如果您想避免每次在查询中进行提升,您可以考虑将其添加到您的映射中,直接添加“提升:因子”。
所以您的映射可能如下所示:
"_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】:使用最新版本的 Elasticsearch(1.3+ 版),您需要使用“功能得分查询”:
http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-function-score-query.html
评分的 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"
【讨论】:
【参考方案4】:如果您使用的是 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)
))))
【讨论】:
以上是关于ElasticSearch——基于字段值提升相关性的主要内容,如果未能解决你的问题,请参考以下文章
Elasticsearch:Rank feature query - 排名功能查询