第五阶段 41 · 相关性调优(boosting、function_score、filter vs query 上下文)

41 · 相关性调优(boosting、function_score、filter vs query 上下文)

阶段:第五阶段 / 进阶与实战

主题:_score 怎么来的、怎么调,以及 filter/query 上下文的性能差异


1. 概念

  • query 上下文 :算 _score(相关性打分),回答「有多匹配」。
  • filter 上下文 :只判断 yes/no,不算分,可缓存、更快,回答「符不符合」。
  • 调分手段:字段 boostboosting 查询(降权而非排除)、function_score(按业务规则改分)。

PostgreSQL 没有相关性评分概念,这是 ES 相对 SQL 的核心增量能力。


2. PostgreSQL 对照

sql 复制代码
-- SQL 没有 _score,只能靠 ORDER BY 表达优先级
SELECT *,
  CASE WHEN geo_cd = 'AP' THEN 2 ELSE 1 END AS weight
FROM salesdata
WHERE material ILIKE '%thinkpad%'
ORDER BY weight DESC;

3. ES DSL

filter 上下文(不算分、可缓存)

复制代码
GET salesdata_idx/_search
{
  "query": {
    "bool": {
      "must":   [ { "match": { "material": "notebook" } } ],   // 算分
      "filter": [ { "term":  { "geo_cd": "AP" } } ]            // 不算分、缓存
    }
  }
}

字段 boost

复制代码
{ "match": { "material": { "query": "notebook", "boost": 3 } } }

function_score(按业务改分)

复制代码
GET salesdata_idx/_search
{
  "query": {
    "function_score": {
      "query": { "match": { "material": "notebook" } },
      "functions": [
        { "filter": { "term": { "geo_cd": "AP" } }, "weight": 2 },
        { "field_value_factor": { "field": "net_amount", "modifier": "log1p" } }
      ],
      "score_mode": "sum",
      "boost_mode": "multiply"
    }
  }
}

4. Spring Boot 实现

java 复制代码
@Component
public class Doc41Relevance {

    @Autowired
    private ElasticsearchClient elasticsearchClient;

    /** must 算分 + filter 精确过滤(不算分、可缓存) */
    public List<Map<String, Object>> searchScored(String indexName, String kw, String geo)
            throws IOException {
        SearchResponse<Map> resp = elasticsearchClient.search(s -> s
                .index(indexName)
                .query(q -> q.bool(b -> b
                        .must(m -> m.match(mt -> mt.field("material").query(kw).boost(3f)))
                        .filter(f -> f.term(t -> t.field("geo_cd").value(geo))))),
                Map.class);

        return resp.hits().hits().stream()
                .map(Hit::source)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
    }
}

想看每条为什么这么打分,可用 explain(.explain(true))或 _explain API 调试。


5. 坑与最佳实践

  1. 精确条件放 filter :等值/范围/枚举放 filter,省去打分开销并利用缓存。
  2. 只想排序不想过滤用 should/boostingboosting 能降权而不是直接排除。
  3. function_score 谨慎 :脚本/函数打分贵,boost_mode/score_mode 要选对。
  4. 别对海量结果排相关性 :能用业务字段排序(日期、金额)就别都靠 _score
  5. 调分先 explain:打分不符预期时用 explain 看每项贡献,别盲改。

相关推荐
sel_93 小时前
【强化学习】Hands-on Modern RL项目实践|OPD 算法完整解析
人工智能·深度学习·算法·机器学习·语言模型
咖啡星人k6 小时前
2026 文生视频:让 AI 把文字变成电影,MonkeyCode 免费上手
人工智能·深度学习·机器学习·计算机视觉·自然语言处理
算AI7 小时前
基于LLM的无人机仿真测试:新方法竞赛夺佳绩
人工智能·深度学习·算法·机器学习·ai
小白说大模型7 小时前
AI驱动的个性化学习路径:知识图谱与知识点关联的存储与推理
大数据·人工智能·学习·mysql·机器学习·prompt·知识图谱
Novlan17 小时前
机器学习
机器学习
硅谷秋水9 小时前
通过技能-驾驭进化实现自我演化的具身智能体
人工智能·深度学习·安全·机器学习·语言模型·机器人
tachibana29 小时前
RAGAS 指标解读
数据库·人工智能·算法·机器学习·架构·大模型·llm
FL162386312910 小时前
电力场景变电站火灾检测数据集VOC+YOLO格式564张2类别
人工智能·yolo·机器学习
网络工程小王10 小时前
【LLM开发实验】 QLoRA实现原理及实战
人工智能·深度学习·机器学习·llm·qlora