Elasticsearch 优先排序较短/不太相关的标题
Posted
技术标签:
【中文标题】Elasticsearch 优先排序较短/不太相关的标题【英文标题】:Elasticsearch ranking shorter/less relevant titles first 【发布时间】:2020-01-03 02:36:57 【问题描述】:我正在使用 Elasticsearch 7.3 进行产品搜索。产品标题的格式不同,但我对此无能为力。
某些标题可能如下所示:
Ford Hub Bearing
还有其他类似的:
Hub bearing for a Chevrolet Z71 - model number 5528923-01
如果有人搜索“雪佛兰轮毂轴承”,“福特轮毂轴承”产品排名第一,雪佛兰零件排名第二。如果我从产品标题中删除所有额外的文本(型号 5528923-01),雪佛兰零件会根据需要排名第一。
很遗憾,我无法修复产品标题,因此当有人搜索 Chevrolet Hub Bearing
时,我需要能够将雪佛兰零件列为 #1。我只是将name
的类型设置为text
,并在我的索引中应用了standard
分析器。这是我的查询代码:
query:
bool:
must: [
multi_match:
fields:
[
'name'
],
query: "Chevrolet Hub Bearing"
]
【问题讨论】:
【参考方案1】:Elasticsearch 将评分公式中的字段长度与 BM25 算法结合使用。这就是为什么较长的文档即使匹配更多的术语也会排在第二位的原因。
我建议您阅读有关 BM25 的精彩博客文章: how-shards-affect-relevance-scoring-in-elasticsearch 和 the-bm25-algorithm-and-its-variables
但您可以调整 bm25 算法来避免这种行为。这是弹性搜索的bm25 documentation 和here a post explaining how to do it
基于 TF/IDF 的相似性具有内置的 tf 归一化并且是 应该更适合短字段(如名称)。见 Okapi_BM25 更多细节。这种相似性有以下选择:
k1 => 控制非线性项频率归一化(饱和度)。 默认值为 1.2。
b => 控制文档长度的程度 标准化 tf 值。默认值为 0.75。
discount_overlaps => 确定是否重叠令牌(位置增量为 0 的令牌) 计算规范时被忽略。默认情况下这是真的,这意味着 计算规范时不计算重叠标记。
所以你应该像这样在索引设置中配置一个新的相似性:
PUT <index>
"settings":
"index":
"number_of_shards": 1
,
"similarity":
"my_bm25_without_length_normalization":
"type": "BM25",
"b": 0
,
"mappings":
"doc":
"properties":
"name":
"type": "text",
"similarity": "my_bm25_without_length_normalization"
然后 if 将停止惩罚更长的得分名称。长度标准化将保留用于其他字段。
【讨论】:
【参考方案2】:乍一看我只有两条建议:
1.在该字段上使用英语分析器。 我相信查询中的术语之间的距离会影响文档的评分,我错了(编辑:正如@Pierre Mallet 所指出的,在 multi_query 中并非如此)并且标准分析器会保留诸如“for”和“a”,这可能会降低文档的分数,因为“for a”被分析器视为标记。
2.如果您有任何类似描述或详细信息的文档,您可以将该字段添加到您的 multi_match 字段列表中,并使用 ^2 调整字段的评分以在数学上操作评分(名称的相关性比相关性更重要的描述,但描述的内容在某些结果上可能是一个很好的决胜局)请参阅以下示例:
"multi_match":
"query": "open source",
"fields": [
"title^2",
"content"
]
您还可以探索 multi_match 的类型参数,它会影响结果评分的行为方式。有关详细信息,请参阅此documentation。
【讨论】:
对于第 1 点,单词之间的距离只考虑词组匹配,而不是简单的多重匹配 投票赞成,因为最终答案是第 2 部分和@PierreMallet 答案的结合。【参考方案3】:我建议将multi_match
的operator
parameter 设置为and
:
"query":
"bool":
"must": [
"multi_match":
"fields": ["name"],
"query": "Chevrolet Hub Bearing",
"operator": "and"
]
and
运算符确保搜索短语中的所有单词都必须出现在结果文档中。仅此设置即可为您提供所需的结果。
【讨论】:
以上是关于Elasticsearch 优先排序较短/不太相关的标题的主要内容,如果未能解决你的问题,请参考以下文章