数据准备,索引my_index002
{ "name" : "C++", "dec" : "i like writing artcle" }, { "name" : "java", "dec" : "i like writing solution artcle" }, { "name" : "solution", "dec" : "i think java is nice" }, { "name" : "php", "dec" : "i think php is nice" }, { "name" : "php", "dec" : "i think php is nice" }搜索name或dec中包含java或solution的document
结果分析:
期望_id=5的文档,但是_id=2和_id=4的文档排在来前面。
计算_id=2的分数,{"match": {"name": "java solution"}},针对_id=2的文档有一个分数 {"match": {"dec": "java solution"}},针对_id=2的文档有一个分数 所以这两个分数加起来:假设这两个分数分别是 1.1+1.2=2.3,matched query数量=2,总query数量=2,得分=2.3*2/2=2.3。
计算_id=5的分数,{"match": {"name": "java solution"}},没有分数 {"match": {"dec": "java solution"}},有一个分数
所以说,只有一个query是有分数的,假设是2.3,matched query数量=1,总query数量=2,得分=2.3*1/2=1.15 < 2.3。
如果期望_id=5的文档排在前面,可以使用best fields策略:dis_max
best fields策略,就是说,搜索到的结果,应该是某一个field中匹配到来尽可能多的关键词,被排在前面;而不是尽可能多的field匹配到来少数的关键词(best fields),排在来前面。dis_max语法直接取多个query中,分数最高的那一个query的分数即可。
计算_id=2的分数,{"match": {"name": "java solution"}},针对_id=2的文档有一个分数 1.1 {"match": {"dec": "java solution"}},针对_id=2的文档有一个分数 1.2 所以这两个分数加起来:假设这两个分数分别是 1.1+1.2=2.3,得分=max(1.1,1.2)=1.2
计算_id=5的分数,{"match": {"name": "java solution"}},没有分数 0 {"match": {"dec": "java solution"}},有一个分数 2.3
所以_id=5的document的得分是max(0, 2.3)=2.3。
考虑一下以下场景:
某个商品,document1,name中包含java,dec中不包含java,solution任何一个关键字某个商品,document2,name中包含solution,dec中不包含任何一个关键字某个商品,document3,name中包含java,dec中包含solution最终搜索出来结果可能是:document1和document2排在document3前面,而不是我们期望的document3排在最前面dis_max只取某个query最大的分数,完全不考虑其他query的分数。
使用tie_breaker可以将其他的query分数也考虑进去。
tie_breaker参数的意义在于将其他query的分数,乘以tie_breaker,然后综合与最高分数的那个query的分数,综合在一起进行计算。
multi_match查询语法如下:
most_fields与best_fields的区别:
1. best_fields,是对多个field进行搜索,挑选某个field匹配度最高的那个分数,同时在多个query最高分相同的情况下,在一定程度上考虑其他query的分数。简单来说,你对多个field进行搜索,就想搜到某一个field尽可能包含更多的关键字的数据。
优点:通过best_fields策略,以及综合考虑其他field,还有minimum_should_match支持,可以尽可能精确地将匹配结果推送到最前面
缺点:除了那些精确匹配的结果,其他差不多大的结果,排序结果不是太均匀,没有什么区分度来
2. most_fields,综合多个field一起进行搜索,尽可能多的让所有field的query参与到总分数的计算中来,此时就是个大杂烩,结果不一定精确,某一个document的一个field包含更多的关键字,但是因为其他document有更过的field匹配到了,所以排在了前面
优点:尽可能将匹配更多field的结果推送到最前面,整个排序结果是比较均匀的
缺点:可能那些精确匹配的结果,无法推送到最前面
wiki明显使用的是most_fields策略,搜索结果比较均匀,但是要翻好几页才能找到最匹配的结果;而baidu使用的则是best_fields。