第二阶段 16 · match_phrase 短语匹配

发布时间:2026/8/2 16:29:02

第二阶段 16 · match_phrase 短语匹配 阶段第二阶段 / 查询能力ES 查询match_phrase| PostgreSQL 对照短语顺序匹配全文-1. 概念match是「命中任意/全部词即可不管顺序」match_phrase要求这些词按顺序、相邻出现像搜「一整个短语」。例如搜carbon laptopmatchlaptop carbon也能命中顺序无所谓match_phrase必须出现carbon紧接着laptop2. PostgreSQL 对照-- 近似全文检索的相邻短语- 表示紧邻SELECT*FROMsalesdataWHEREto_tsvector(english,description) phraseto_tsquery(english,carbon laptop);PG 的phraseto_tsquery/-就是短语顺序匹配等价于match_phrase。3. ES DSL基本短语GET salesdata_idx/_search { query: { match_phrase: { description: carbon laptop } } }允许词间有间隔slopGET salesdata_idx/_search { query: { match_phrase: { description: { query: carbon laptop, slop: 2 } } } }slop: 2允许两个词之间最多间隔 2 个位置如carbon x1 laptop也能命中。前缀短语搜索框实时补全常用GET salesdata_idx/_search { query: { match_phrase_prefix: { description: carbon lap } } }最后一个词按前缀匹配适合「输入时联想」。4. Spring Boot 实现ComponentpublicclassDoc16MatchPhraseQuery{AutowiredprivateElasticsearchClientelasticsearchClient;/** 严格短语词按顺序相邻 */publicListMapString,Objectphrase(StringindexName,Stringfield,Stringphrase)throwsIOException{SearchResponseMaprespelasticsearchClient.search(s-s.index(indexName).query(q-q.matchPhrase(m-m.field(field).query(phrase))),Map.class);returntoSourceList(resp);}/** 带 slop允许词间间隔 */publicListMapString,ObjectphraseWithSlop(StringindexName,Stringfield,Stringphrase,intslop)throwsIOException{SearchResponseMaprespelasticsearchClient.search(s-s.index(indexName).query(q-q.matchPhrase(m-m.field(field).query(phrase).slop(slop))),Map.class);returntoSourceList(resp);}privateListMapString,ObjecttoSourceList(SearchResponseMapresp){returnresp.hits().hits().stream().map(Hit::source).filter(Objects::nonNull).collect(Collectors.toList());}}返回强类型 Java 对象推荐替代裸 Map把Map.class换成 DTO 的Class第 11 篇定义的OrderDoc用JsonProperty映射下划线字段即可直接拿到强类型列表/** 严格短语返回 ListOrderDoc */publicListOrderDocphraseTyped(StringindexName,Stringfield,Stringphrase)throwsIOException{SearchResponseOrderDocrespelasticsearchClient.search(s-s.index(indexName).query(q-q.matchPhrase(m-m.field(field).query(phrase))),OrderDoc.class);// ← 关键DTO 的 Class而非 Map.classreturnresp.hits().hits().stream().map(Hit::source).filter(Objects::nonNull).collect(Collectors.toList());}临时/探索性查询仍可用Map.class对外/长期维护接口建议统一用 DTO。5. 坑与最佳实践只对text有意义短语基于分词后的词项位置keyword不适用。slop不是模糊它控制词间距不纠错拼写。match_phrase_prefix慎用大数据量最后一个词做前缀扩展可能较慢可限制max_expansions。顺序敏感这是它和match的本质区别选型时想清楚要不要顺序。下一篇17-multi_match-多字段.md。

相关新闻