elasticsearch - Elasticsearch 优先排序较短/不太相关的标题
问题描述
我正在使用 Elasticsearch 7.3 进行产品搜索。产品标题的格式不同,但我对此无能为力。
有些标题可能如下所示:
Ford Hub Bearing
和其他这样的:
Hub bearing for a Chevrolet Z71 - model number 5528923-01
如果有人搜索“雪佛兰轮毂轴承”,“福特轮毂轴承”产品排名第一,雪佛兰零件排名第二。如果我从产品标题中删除所有额外的文本(型号 5528923-01),雪佛兰零件会根据需要排名第一。
不幸的是,我无法修复产品标题,因此当有人搜索时,我需要能够将雪佛兰零件列为#1 Chevrolet Hub Bearing
。我只是将类型设置name
为并在我的索引中text
应用了分析器。standard
这是我的查询代码:
{
query:{
bool: {
must: [
{
multi_match:{
fields:
[
'name'
],
query: "Chevrolet Hub Bearing"
}
}
]
}
}
}
解决方案
Elasticsearch 使用 BM25 算法的评分公式中的字段长度。这就是为什么较长的文档即使匹配更多的术语也会排在第二位的原因。
我建议您阅读有关 BM25 的精彩博客文章: how-shards-affect-relevance-scoring-in- elasticsearch 和 the-bm25-algorithm-and-its-variables
但是您可以调整 bm25 算法来避免这种行为。这是elasticsearch的bm25文档,这里是解释如何做的帖子
基于 TF/IDF 的相似性具有内置的 tf 规范化,应该更适合短字段(如名称)。有关详细信息,请参阅 Okapi_BM25。这种相似性有以下选择:
k1 => 控制非线性项频率归一化(饱和度)。默认值为 1.2。
b => 控制文档长度标准化 tf 值的程度。默认值为 0.75。
discount_overlaps => 确定在计算 norm 时是否忽略重叠标记(位置增量为 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"
}
}
}
}
}
然后,如果将停止惩罚更长的得分名称。长度标准化将保留用于其他字段。
推荐阅读
- python - 集合是无序的,但它仍然支持 2 集合的减法,它在内部是如何工作的?
- java - 如何从ansible下载jar文件
- lambda-calculus - 为什么在 λ-演算中引入 Ycombinator 是必要的?
- reactjs - 使用 React Router 更改路由时导航栏组件位置不会更新
- json - 'utf-8' codec can't decode byte 0xf0 in position 12 on LZ4 and Python 3.x
- php - PHP MySQL localhost 连接问题
- sql - 如何使用内部联接和子查询将 SQL 查询转换为 LINQ lambda 表达式
- mysql - 如何在 MySql 或 R 中获取存储桶的天数
- c++ - 如何在没有模板的情况下将左值传递给仅采用右值的函数
- amazon-web-services - Terraform - AWS - 创建多个实例 - 不同的 AZ(其中实例数大于 AZ 列表长度)