文章内容收录到个人网站,方便阅读: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
降序。 🚀