15 · prefix / wildcard / fuzzy 模糊匹配阶段第二阶段 / 查询能力ES 查询prefix/wildcard/fuzzy| PostgreSQL 对照LIKE abc%/LIKE %x%/ 模糊纠错1. 概念三种「非精确」匹配都作用在keyword或 text 的词项上ES 查询作用SQL 对应prefix前缀匹配LIKE abc%wildcard通配符匹配*多字符?单字符LIKE %x%/LIKE a?cfuzzy允许拼写误差编辑距离PG 没有直接语法近似pg_trgm⚠️ 这三种都可能很慢尤其前置通配*abc生产环境慎用大范围。2. PostgreSQL 对照-- prefixSELECT*FROMsalesdataWHEREinvoice_numberLIKEINV-2026%;-- wildcard包含SELECT*FROMsalesdataWHEREinvoice_numberLIKE%2026%;-- fuzzy拼写容错PG 需 pg_trgm 扩展SELECT*FROMsalesdataWHEREmaterial%ThinkPd;-- 相似度3. ES DSLprefix前缀GET salesdata_idx/_search { query: { prefix: { invoice_number: INV-2026 } } }wildcard通配符GET salesdata_idx/_search { query: { wildcard: { invoice_number: *2026* } } }fuzzy拼写容错GET salesdata_idx/_search { query: { fuzzy: { material: { value: ThinkPd, fuzziness: AUTO } } } }fuzziness: AUTO会根据词长自动决定允许的编辑距离通常 1~2。4. Spring Boot 实现ComponentpublicclassDoc15FuzzyQuery{AutowiredprivateElasticsearchClientelasticsearchClient;/** LIKE prefix% */publicListMapString,Objectprefix(StringindexName,Stringfield,Stringprefix)throwsIOException{SearchResponseMaprespelasticsearchClient.search(s-s.index(indexName).query(q-q.prefix(p-p.field(field).value(prefix))),Map.class);returntoSourceList(resp);}/** LIKE %pattern%pattern 里用 * 和 ? */publicListMapString,Objectwildcard(StringindexName,Stringfield,Stringpattern)throwsIOException{SearchResponseMaprespelasticsearchClient.search(s-s.index(indexName).query(q-q.wildcard(w-w.field(field).value(pattern))),Map.class);returntoSourceList(resp);}/** 拼写容错 */publicListMapString,Objectfuzzy(StringindexName,Stringfield,Stringvalue)throwsIOException{SearchResponseMaprespelasticsearchClient.search(s-s.index(indexName).query(q-q.fuzzy(f-f.field(field).value(value).fuzziness(AUTO))),Map.class);returntoSourceList(resp);}privateListMapString,ObjecttoSourceList(SearchResponseMapresp){returnresp.hits().hits().stream().map(Hit::source).filter(Objects::nonNull).collect(Collectors.toList());}}5. 坑与最佳实践前置通配符*abc极慢等于全表扫倒排词典能避免就避免必要时用wildcard字段类型或 n-gram。作用在keyword上对分词后的text用 wildcard 结果常常反直觉。大小写keyword默认大小写敏感wildcard也是。需要不敏感可加case_insensitive: true8.x 支持。fuzzy 有性能代价编辑距离越大越慢AUTO通常够用。能用prefix就别用wildcard前缀匹配比通配快得多。下一篇16-match_phrase-短语.md。
第二阶段 15 · prefix / wildcard / fuzzy 模糊匹配
15 · prefix / wildcard / fuzzy 模糊匹配阶段第二阶段 / 查询能力ES 查询prefix/wildcard/fuzzy| PostgreSQL 对照LIKE abc%/LIKE %x%/ 模糊纠错1. 概念三种「非精确」匹配都作用在keyword或 text 的词项上ES 查询作用SQL 对应prefix前缀匹配LIKE abc%wildcard通配符匹配*多字符?单字符LIKE %x%/LIKE a?cfuzzy允许拼写误差编辑距离PG 没有直接语法近似pg_trgm⚠️ 这三种都可能很慢尤其前置通配*abc生产环境慎用大范围。2. PostgreSQL 对照-- prefixSELECT*FROMsalesdataWHEREinvoice_numberLIKEINV-2026%;-- wildcard包含SELECT*FROMsalesdataWHEREinvoice_numberLIKE%2026%;-- fuzzy拼写容错PG 需 pg_trgm 扩展SELECT*FROMsalesdataWHEREmaterial%ThinkPd;-- 相似度3. ES DSLprefix前缀GET salesdata_idx/_search { query: { prefix: { invoice_number: INV-2026 } } }wildcard通配符GET salesdata_idx/_search { query: { wildcard: { invoice_number: *2026* } } }fuzzy拼写容错GET salesdata_idx/_search { query: { fuzzy: { material: { value: ThinkPd, fuzziness: AUTO } } } }fuzziness: AUTO会根据词长自动决定允许的编辑距离通常 1~2。4. Spring Boot 实现ComponentpublicclassDoc15FuzzyQuery{AutowiredprivateElasticsearchClientelasticsearchClient;/** LIKE prefix% */publicListMapString,Objectprefix(StringindexName,Stringfield,Stringprefix)throwsIOException{SearchResponseMaprespelasticsearchClient.search(s-s.index(indexName).query(q-q.prefix(p-p.field(field).value(prefix))),Map.class);returntoSourceList(resp);}/** LIKE %pattern%pattern 里用 * 和 ? */publicListMapString,Objectwildcard(StringindexName,Stringfield,Stringpattern)throwsIOException{SearchResponseMaprespelasticsearchClient.search(s-s.index(indexName).query(q-q.wildcard(w-w.field(field).value(pattern))),Map.class);returntoSourceList(resp);}/** 拼写容错 */publicListMapString,Objectfuzzy(StringindexName,Stringfield,Stringvalue)throwsIOException{SearchResponseMaprespelasticsearchClient.search(s-s.index(indexName).query(q-q.fuzzy(f-f.field(field).value(value).fuzziness(AUTO))),Map.class);returntoSourceList(resp);}privateListMapString,ObjecttoSourceList(SearchResponseMapresp){returnresp.hits().hits().stream().map(Hit::source).filter(Objects::nonNull).collect(Collectors.toList());}}5. 坑与最佳实践前置通配符*abc极慢等于全表扫倒排词典能避免就避免必要时用wildcard字段类型或 n-gram。作用在keyword上对分词后的text用 wildcard 结果常常反直觉。大小写keyword默认大小写敏感wildcard也是。需要不敏感可加case_insensitive: true8.x 支持。fuzzy 有性能代价编辑距离越大越慢AUTO通常够用。能用prefix就别用wildcard前缀匹配比通配快得多。下一篇16-match_phrase-短语.md。