字节二面:Elasticsearch搜索,在搜索用到分词后,返回的第一条可能不是最匹配name的数据,这种如何解决?

文章内容收录到个人网站,方便阅读:hardyfish.top/

资料分享 LangChain实战课

课程链接:time.geekbang.org/column/intr...

资料链接:url81.ctfile.com/f/57345181-...

访问密码:3899

AI大模型项目落地实战

课程链接:time.geekbang.org/column/intr...

资料链接:url81.ctfile.com/f/57345181-...

访问密码:3899

在 Elasticsearch(ES)中:

  • 不分词 时(keyword 类型),可以按照 id 降序排序,结果符合预期。
  • 分词后text 类型),搜索 name,匹配度(_score)可能不准确,返回的第一条可能不是最匹配 name 的数据,导致排序和相关性变差。

核心原因

  • ES 默认使用 BM25 算法计算 _score

    ,分词后:

    • 匹配的单词分布影响评分(词频、文档频率)。
    • 短字段 vs 长字段的评分不同 ,可能短的 name 反而 _score 低。
    • 完全匹配的词可能被打散 ,导致排序不如 keyword 直观。

解决方案

为了解决 分词后 name 匹配度下降 的问题,可以采用以下策略:

1. match_phrase 保证短语匹配

  • match_phrase 要求 完整匹配,并按顺序出现,不会因为单个词的 BM25 计算影响匹配度:
json 复制代码
{
  "query": {
    "match_phrase": {
      "name": "你的搜索词"
    }
  }
}

适用于短语查询,避免被拆分后的单词乱序影响相关性。

2. bool 组合查询,提高精准匹配优先级

  • 结合 term(精准匹配 keyword) 和 match(分词匹配 text),提高完全匹配的权重:
json 复制代码
{
  "query": {
    "bool": {
      "should": [
        { "term": { "name.keyword": "你的搜索词" } },
        { "match": { "name": "你的搜索词" } }
      ]
    }
  }
}

term 让完全匹配的 name.keyword 评分更高,match 兼顾模糊匹配。

3. boost 提高 name 相关性

如果 match 计算的 _score 过低,可以提升 name 权重:

json 复制代码
{
  "query": {
    "match": {
      "name": {
        "query": "你的搜索词",
        "boost": 3
      }
    }
  }
}

提高 name_score 计算中的影响,避免低评分影响排序。

4. function_score 结合 id 排序

如果希望在 匹配度高时,同时按照 id 降序排列

json 复制代码
{
  "query": {
    "function_score": {
      "query": {
        "match": { "name": "你的搜索词" }
      },
      "functions": [
        {
          "field_value_factor": {
            "field": "id",
            "factor": 1,
            "modifier": "log1p",
            "missing": 1
          }
        }
      ],
      "score_mode": "sum",
      "boost_mode": "multiply"
    }
  }
}

匹配度相同时,id 大的排前面,不影响 _score 排序。

5. _score + id 组合排序

如果 id 降序比 _score 更重要,可以调整排序:

json 复制代码
{
  "query": {
    "match": { "name": "你的搜索词" }
  },
  "sort": [
    { "_score": "desc" },
    { "id": "desc" }
  ]
}

_score 优先排序,匹配度相同时 id 降序。

最终推荐方案

如果你希望 name 高匹配度优先,同时 id 降序:

json 复制代码
{
  "query": {
    "bool": {
      "should": [
        { "term": { "name.keyword": "你的搜索词" } },
        { "match": { "name": { "query": "你的搜索词", "boost": 2 } } }
      ]
    }
  },
  "sort": [
    { "_score": "desc" },
    { "id": "desc" }
  ]
}

这样可以保证 name 完全匹配的 _score 高,且按 id 降序。 🚀

相关推荐
严同学正在努力4 分钟前
从备份到恢复:我用 30 分钟恢复了误删的核心业务表
android·java·数据库·ai
Csvn1 小时前
📊 SQL 入门 Day 11:CASE 表达式:SQL 里的 if-else 魔法
后端·sql
QQ_21696290961 小时前
Spring Boot 养老院管理系统:从入住、护理到费用结算的全流程实现(源码可领)
java·spring boot·后端
cxoptics1 小时前
冰洲石分束器设计与应用
java
ck-joker1 小时前
M1 Pro跑LLM实测:Ollama+LangChain4j零成本本地大模型开发,比云端API快在哪?
java·语言模型
乐思智能科技有限公司2 小时前
PLECS软件学习使用(二)直流电机基本系统模型
人工智能·算法·机器学习·面试·职场和发展
丙氨酸長鏈2 小时前
[Bukkit插件开发]手持发射器箭矢机枪 教学文档 面向Python/C#开发者入门Java与Bukkit API
java·python·c#
Nontee2 小时前
设计模式:模板方法与策略,从“每个字都认识“到能说清它们在干嘛
java·数据库·设计模式
我是唐青枫2 小时前
Java ReentrantLock 实战详解:比 synchronized 更灵活的可重入锁
java·开发语言
GitLqr2 小时前
深度拆解 Dart 事件循环:从面试题看清 Microtask 与 Event Queue 的执行顺序
flutter·面试·dart