ES 计算相似度的算法为 TF/IDF(检索词频率/反向文档频率)
单个次匹配
(1)字段长度准则:document 的长度越长,相关性越低。
(2)检索词频率准则:关键字在 document 中出现频率越高,相关性也越高。
多个次匹配
(1)反向 document 频率准则:对于每个检索关键字而言,在 Index 中出现的频率越高,其相对的相关性占比越低。
match 是 全文搜索,只要发现和搜索条件相关的 document,都会出现在最终的结果集中,并且 ES 会根据结果相关性评分来对结果集进行排序,结果可以是匹配部分关键字,但评分低。
match_phrase 是 邻近短语搜索,会将给定的短语当成一个完整的查询条件。当使用match_phrase进行搜索的时候,结果集都必须包含指定的查询词组。
场合:match_phrase 是短语搜索,主要用于多个词组成短语的邻近搜索,需要邻近短语的评分更高一点;
效率:match_phrase 是在搜索阶段进行的计算,会影响搜索效率,据说比 term 查询慢20倍,因此应该避免对大文本量的字段搜索,尽量进行标题,名字这种短类型的搜索才使用这个;
使用:建议使用 match_phrase 时使用标准的一个个分词,这样是方便进行邻近搜索的控制的,如果使用 ik 等分词,执行 match_phrase 时分词是不可控的,所以结果也是不可控。match 使用 ik,match_phrase 用 standard 结合一起使用也是可以的。
优化:
(1)可以通过增加词库的方式进行单纯使用 match 匹配效率是最高的,前提是你知道会搜索什么;
(2)想提高性能可以通过先使用 match 进行过滤数据,然后利用 rescore api 对已经 match 的结果进行加分,这样就减少了部分不必要的非 match 过滤;
GET test_index/_search { "query": { "match": { "name":"东方宾馆" } }, "rescore": { "window_size": 30, "query": { "rescore_query": { "match_phrase": { "name": { "query": "东方宾馆", "slop": 0 } } } } } }
#window_size 是每一分片进行重新评分的顶部文档数量这个只要大于你可能分页的总数*每页的数量即可(pageNumber*pageSize)实际上不需要这么多因为翻页不可能很深,这个根据业务调整即可。
(1)match query 比 match_phrase 的性能要高 10 倍,比 proximity match(带slop的)性能要高20倍;
(2)match_phrase 据说比 term 查询慢 20 倍。
es 基于match_phrase/fuzzy的模糊匹配原理及使用:https://www.cnblogs.com/danvid/archive/2004/01/13/10570334.html
ES查询-match VS match_phrase:https://blog.csdn.net/liuxiao723846/article/details/78365078
TF-IDF算法介绍及实现:codenong.com/25813995/
ES 搜索10 (match、match_phrase 性能优化):https://blog.csdn.net/qq_42383787/article/details/99967622