前言
type 类型介绍
text:
默认分词,将字符串分成若干个词,创建索引。同时,保存一份不分词的字符串,保存在索引中(默认最多保存256个字符)。例:“hello world” ,filed索引:hello,world ,field.keyword索引中存放hello word。
一. 查询
term query(短语搜索)
查询字符不分词,将查询的条件当做一个整体进行查询
filter query(过滤搜索)
优势在于会caching,增加或删除数据,会自动更新。实际上缓存的并不是一个完整的doc list数据结果,而是将filter bitset缓存起来(对于小的数据量,是不会进行缓存的),下次不需要扫码倒排索引了。大部分情况下,是在query之前执行,尽量过滤到尽可能多的数据。query会计算相关度分数,并根据相关度分数进行排序。而filter只是过滤结果,不进行相关的计算和排序。
math query(匹配搜索)
默认分词,进行精确度查询时,可以指定operator为and,进行查询。示例如下:{"query":{"match":{"title":{"query":"java elasticsearch","operator":"and"}}}}; 也可以指定匹配率,进行查询。示例如下:{"query":{"match":{"title":{"query":"java elasticsearch test hadoop","minimum_should_match":"75%"}}}}
prefix query (前缀搜索)
前缀搜索,查询以搜索词开始的doc。例如查询:C4,则可以查询到C412,但是不能查询到2C4。类似mysql的模糊搜索中的"C4%"。语法:{"query":{"prefix":{"position.keyword":{"value":"C4"}}}}
wildcard query(通配符搜索)
通配符搜索,?代表以为字符,*代表0到任意多个字符。性能比较差,需要扫描所有的倒排索引。尽力不要用。查询语法:{"query":{"wildcard":{"position.keyword":{"value":"*s?f*"}}}}
regexp query(正则搜索)
正则搜索,[0-9]:指定范围的数字,[a-z]:指定范围的字符,. :代表一个字符,+:代表前面的正则表达式可以出现一个到多个。查询语法:{"query":{"regexp":{"position.keyword":{"value":"s[a-z].+"}}}}
二. 查询策略
best fields 查询策略
dis_max参数:多条件查询时,尽量将一个条件中匹配度最高的排在前面,而不是将多个条件组合匹配度高的排在前面。例:查询条件:“title”:“java elasticsearch” ,content:“java elasticsearch”,不是将分词后的查询中既满足title查询条件,又满足content查询条件的排在前面。而是分别对各个查询条件进行查询,分别计算相关度分数,然后将其中查询相关分数最高的排在前面。语法:{"query":{"dis_max":{"queries":[{"match":{"title":"java elasticsearch"}},{"match":{"content":"java elasticsearch"}}]}}}
tie_breaker参数: dis_max 只取最大的,不考虑其他查询条件的相关度分数,会出现查询结果特别不准确的情况。这时候需要引入tie_breaker参数。其他的查询条件*tie_breaker ,再加上最大相关度分数。综合计算新的相关度分数。语法:{"query":{"dis_max":{"queries":[{"match":{"title":"java elasticsearch"}},{"match":{"content":"java elasticsearch"}}],"tie_breaker":0.3}}}
语法:{"query":{"multi_match":{"query":"use china finance manager","type":"best_fields","fields":["country","position"]}}}
most fields 查询策略
尽可能将匹配更多field的结果优先返回回来,如下(会将country和postion都匹配的优先返回)。 语法:{"query":{"multi_match":{"query":"use china finance manager","type":"most_fields","fields":["country","position"]}}}
弊端:知道尽可能到的field匹配的doc,而不是完全匹配的doc;不能使用minimun_should_match 去掉不满足条件的长尾结果。 相关度分数计算方法很复杂,可能会将出现频率低filed的匹配计算的分数特别大,导致优先返回,跟预计的搜索结果相差很大 。
解决思路:将多个fields 合并为一个field。进行查询。es中提供copy_to 属性。可以将多个field合并到一个field。
cross filed 查询策略
尽可能多的field中匹配,而不是某个field中匹配。跟most_fields的区别在于cross_fields支持operator属性,可以满足每个term都必须在一个filed中出现。不加operator的话,跟most_fields查询结果几无差别。查询语法:{"query":{"multi_match":{"query":"manager china","type":"cross_fields","operator":"and","fields":["position","country"]}}}
三. 近似查询
1.match_phase 模糊匹配
类似于sql查询的模糊查询。例如:查询java spark ,是将查询条件作为一个短语进行模糊查询。要求java和spark符合查询条件,且必须相连。查询原理:查找到既包含java,又包含spark的doc之后,计算java和spark的位置。如果正好相邻且满足查询时的顺序,则返回。查询语法:{"query":{"match_phrase":{"position":{"query":"senor software"}}}}
2. proximiy match 近似匹配
使用match_phase和slop 进行移位查询。
类似模糊查询,但是可以指定term之间相距的位置差。例如:java spark 查询,指定slop为1.则不仅可以模糊查询到java spark 相连的数据,还可以查询到java and spark中间间隔为1的数据;同理指定为n,则允许java和spark最多相差n位。查询语法:{"query":{"match_phrase":{"position":{"query":"senor software","slop":2}}}}
3. match_phrase_prefix 前缀近似匹配
原理和match_phrase相似,唯一的区别是会将最后一个term作为前缀进行搜索。但是只会将最后一个term作为前缀。max_expansions参数:指定term最多匹配多少个。查询语法:{"query":{"match_phrase_prefix":{"position.keyword":{"query":"technique so","max_expansions":10}}}}
4.解决问题:
解决即想查询java,又想查询spark。并且尽可能将java和spark相距越近的排在前面,相距远的排在后面,只匹配一个的term的排在最后面。
查询语法:{"query":{"bool":{"must":[{"match":{"position":"senor manager"}}],"should":[{"match_phrase":{"position":{"query":"senor manager","slop":1}}}]}}}
rescore: 重打分
语法:{"query":{"match":{"position":"senor manager"}},"rescore":{"query":{"rescore_query":{"match_phrase":{"position":{"query":"senor manager","slop":1}}}},"window_size":50}} 其中:window_size表示对前多少个重打分。slop 标识term之间position相差的位数。