一 概念
-
请求上下文 如下图 即是es请求上下文 常见的一些字段
{ "took" : 50, //表示当前请求消耗了多少时间 单位毫秒 "timed_out" : false, //表示当前请求是否超时 "_shards" : { //表示当前请求的分片 "total" : 1, //表示当前请求没有跨分片 只命中了一个分片 "successful" : 1, //请求成功的分片数 1个 "skipped" : 0, //请求跳过的分片数 0 个 "failed" : 0 //请求失败的分片数 0个 }, "hits" : { //表示es查询命中的结果 "total" : { //表示总数 "value" : 3, //表示当前查询到的总记录数一共3条 "relation" : "eq" //表示当前查询的关系是= }, "max_score" : 1.0, //表示当前最大的评分为1.0 "hits" : [ //返回的记录(数组) { "_index" : "index_test", //当前查询命中的索引 "_type" : "_doc", //表示当前的类型为_doc "_id" : "3", //文档的id "_score" : 1.0, //评分 "_source" : { //文档中的内容 也叫元数据 "product_name" : "sanxing", "desc" : "三星手机", "price" : 6999, "tags" : [ "gaoduan", "lappai", "nfc" ] } }, { "_index" : "index_test", "_type" : "_doc", "_id" : "4", "_score" : 1.0, "_source" : { "product_name" : "pingguo", "desc" : "苹果手机", "price" : 9999, "tags" : [ "gui", "haokan", "nfc" ] } }, { "_index" : "index_test", "_type" : "_doc", "_id" : "2", "_score" : 1.0, "_source" : { "product_name" : "huawei", "desc" : "华为P40", "price" : 5999, "tags" : [ "xingjiabi", "guochan", "nfc" ] } } ] } }
相关度评分 相关度评分即上面上下文中的每个文档中的_score字段 如果查询的时候没有指定排序的规则 则默认按照相关度来进行排序 相关度评分越高
元数据 元数据即上面上下文中每个文档中的_source字段
二 常用查询操作
2.1 禁用_source
- 好处 禁用 _source则在查询的时候 不会显示 _souce字段 可以节省内存开销
-
坏处
- 不支持update、update_by_query和reindex api
- 不支持高亮
- 不支持reindex 更改mapping分析和版本升级
- 备注 如果希望节省磁盘 可以压缩索引
- 查询时禁用souce 有3种常用的方式 1、"_source":"{false}" 这个是禁用所有的元数据 2、" _source":["field1","field2"] 3、利用 excludes 和 includes 具体示例如下面的三张图 includes与excludes是可以支持通配符匹配的 excludes与includes存在相同的字段的时候 以excludes字段为准 即如果includes与excludes字段都包含price字段 则最终查询的结果不会包含price字段。
-
通过mapping禁用souce 不太建议这种方式 因为mapping是不能被修改的
2.2 ES Query查询
#query查询语法 GET /index_name/_search?q=param1:val1&?q=param2:va2
GET /index_test/_search?q=product_name:pingguo
Query查询示例-单条件查询
Query查询示例-多条件查询
Query查询示例-模糊匹配
之前上面的两个示例 无论是单条件查询还是多条件查询 他们其实都是针对某一个或某几个字段进行精准匹配 如果在查询的时候不带这种条件则会利用倒排索引进行查询 即会将文档中出现过该词的文档全部筛选出来
#query查询分页语法 GET /index_name/_search?from=xx&size=xx from表示从哪个位置开始往下查 size表示分页的大小 sort表示排序的规则
GET /index_test/_search?from=0&size=1&sort=price:desc
分页查询示例
2.3 全文检索
全文检索的基本语法如下
/index_name/_search
{
"query":{
xxx
}
}
#示例如下 查询product_name 包含huawei这个词项的所有文档product_name 这个字段类型是text
GET /index_test/_search
{
"query": {
"match": {
"product_name": "huawei"
}
}
}
除了上面示例的match之外 全文检索还包含其他的项 主要有下面4种
- match 表示匹配包含某个term的字句
- match_all 表示匹配所有结果的字句
- multi_match 多字段条件
- match_phrase 短语查询 匹配包含短语中所有词项的子句
match查询示例
match_all查询示例
match_all查询等同于 GET /index_test/_search search不带任何的条件
multi_match查询示例
match_phrase查询示例
2.4 精确匹配
精确匹配也就是term查询 精确匹配和全文检索的区别主要是 精确匹配不会对搜索词进行分词 而全文检索则会对搜索词进行分词
-
term 匹配和搜索词项完全相等的结果
- term和match_phrase的区别: match_phrase会将检索的关键词分词 match_phrase的分词结果必须在被检索的字段的分词中都包含 而且顺序必须相同 term搜索则不会将搜索词分词
- term和keyword的区别: term是对搜索词不分词 keyword是对于source中的字段的内容不分词
- terms 匹配和搜索词项列表中任意项匹配结果
- range 范围查找
term查询示例
在上面全文检索示例中我们可以看到index_test索引是包含一个product_name为huawei P40的文档的 其id为6
terms 查询示例
range查找
2.5 filter查询
filter查询与match这些查询的区别 filter不再进行相关度的评分 filter查询出来的数据相关度评分都是同一个值
bool查询中设置filter查询
2.6 bool查询
bool查询又叫布尔查询 它有如下几个要素
-
bool 可以组合多个查询条件 bool查询也采用more_matches_is_better的机制 因此满足must和should子句的文档将被合并起来计算分值
- must 表示查询中必须满足的条件 must中的条件都是and关系 计算相关度评分
- filter 过滤器 不计算相关度评分
- should 相当于or查询 should中的条件都是or的关系 计算相关度评分
- must_not 必须不满足的条件 不计算相关度评分
- minimum_should_match 指定的should返回的文档必须满足的数量或百分比 如果一个bool查询中至少包含一个should子句而没有must或filter子句 则默认为1 否则默认为0
bool查询示例
-
must子句
bool查询示例 查询product_name 包含huawei这个词项 且price=6999的文档 -
filter子句
filter子句和must子句达到的效果是一样的 不同的是 filter子句不计算相关度评分 而must子句计算相关度评分 -
must_not子句
must_not子句在bool查询中表示文档中必须不包含某个条件 而且它不会计算相关度评分 -
should子句
-
多种子句组合查询
filter与must子句组合 虽然效果等同于两个must组合 但是效率不一样 filter子句是不计算相关度评分的 所以它相当于先进行filter计算,将数据过滤一遍 然后再对过滤后的数据进行must匹配 这样提高了查询效率。filter或者must子句 与should子句组合 这种方式组合 should子句的条件可以都不满足
多子句组合查询中如何使得should子句生效