Elasticsearch查询语法
关于倒排索引的一点思考:
ES在保存文档时,会将原始文档通过_source字段保存,同时构建倒排索引,保存词项跟文档ID的关系。那么接下来有一个问题:一个Type有一个倒排索引,还是一个Field对应一个倒排索引?
假设一个Type一个倒排索引,那么文档中所有分词的字段,都会进入这个唯一的倒排索引表里。举个例子,Type包含title字段和content字段,文档A的title和content都包含java这个词项,文档B只有content中包含java这个词项,那么在这个唯一的倒排索引表中,java词项对应A、B两个文档,你如果查询title中包含java词项时,ES就不知道要给你返回文档A还是B了!!!
所以,倒排索引是在Field维度,那么在组合查询时,即有多个查询条件,ES是如何处理的呢?比如查询title中包含java词项,content中包含作者Bruce Eckel的文档。那么,假设title的倒排索引表里,包含java的文档有A、B、C,在content的倒排索引里包含Bruce Eckel的文档有A、D、E,那么计算这2个倒排索引表结果的交集,即A就是满足条件的文档。
故在组合查询时,最终的结果为每个查询子项结果集的交集
cat API
查询当前ES集群相关的消息,包括集群中index数量、运行状态、当前几圈所在的ip,目的在于将查询的结果以更有好的方式输出
- _cat: 输出
_cat api
中所有支持的查询命令; - _cat health: 检查es集群运行的状态
- _cat count: 可以快速的查询集群或者index中文档的数量
- _cat indices: 查询当前集群中所有的index的数据,包括index的分片数、document的数量、存储所用的空间大小
Search API
REST request URI:轻便快捷的URI查询方法
REST request body:可以有许多限制条件的json格式查询方法
- query:在请求消息体中的
query
允许我们使用Query DSL
的方式查询。- term: 不会对被查询词项进行分词,以查询词项为‘中国人’为例,查询结果覆盖like ‘%中国人’, like ‘%中国人%’,like '中国人%'的场景,即判断某个document是否包含词项,但不会查出来“国人素质堪忧”、“中国加油”、“人类是大自然的一部分”这样的文档。
- match:将被查询值进行分词,分词后的任意一个词项被匹配,文档就会被搜到。
- match_phrase:match的升级版,分词后所有的词项都要被匹配到,并且文档中词项的顺序跟查询条件中词项的顺序一致。
- bool:可以把任意多个简单查询组合在一起,通常和must 、should、must_not、filter一起组合出复杂的查询
- range: 查询时指定某个字段在某个特定的范围
# 在term查询条件下,中国人不会被拆分为 中国、国人、人 # 在match查询条件下,会被拆分,并且任意一个词项被命中,文档就会被搜到 # 在match_phrase查询条件下,所有词项都必须被命中,并且顺序也要一致。 "query" : { "term": { "title": "中国人" } } # 查询title中包含关键词java,并且价格不能高于70,description可以包含也可以不包含虚拟机的书籍 # must 文档必须匹配must选项下的查询条件,相当于逻辑运算中的AND # should 文档可以匹配should选项下的查询条件,也可以不匹配,相当于逻辑运算中的or # must_not 与must相反,匹配该查询条件下的文档,不会被返回。 # filter 跟must一样,匹配filter选项下的查询条件文档才会被返回,但是filter不评分,只起到过滤作用。 "query": { "bool": { "minimum_should_match": 1, "must": { "match": {"title": "java"} }, "should": [ {"match": {"description": "虚拟机"}} ], "must_not": { "range": {"price": {"gte": 70}} } } }
- 聚合查询
- 简单聚合,比如查询文档中最大、最小、平均值、合计等
# 以index为books为例,在ES 7.X中没有type概念,books中_doc的mapping如下 { "books": { "mappings": { "properties": { # 书籍ID "id": { "type": "long" }, # 书籍状态 "status": { "type": "long" }, # 书籍名称 "title": { "type": "text", "analyzer": "ik_max_word" }, # 书籍描述 "description": { "type": "text", "analyzer": "ik_max_word" } } } } } # 简单聚合查询 GET books/_search { "aggs": { # 聚合后的字段名 "max_price": { # 书中的最高价 "max": {"field": "price"} } } }
- 桶聚合,类似SQL中的GROUP BY
# 根据language字段对books索引中的文档进行分组,统计属于各种编程语言的书的数量 POST books/_search { "aggs": { "per_count": { # terms用于分桶聚合 "terms": { "field": "language" } } } } # 常见的筛选后进行分组聚合,比如 id大于7的文档按状态聚合 { "query": { "bool": { "must": { "range": { "id": {"gte": 7} } } } }, "aggs": { "per_count": { "terms": { "field": "status"} } } }
query查询和filter查询的区别
query:适用于全文检索;会计算相关得分
例如:
URI: /yourIndex/yourType/_search
BODY:
{
"query": {
"bool": {
"must": {
"match": {
"wareName": "阿迪达斯"
}
}
}
}
}
filter:针对结构化数据,适用于完全精确匹配,范围检索(比如时间戳是否在2015~2016之间,状态是否为通过);不涉及评分,没有额外的相关度排名
例如:
URI: /yourIndex/yourType/_search
BODY:
{
"filter": {
"bool": {
"must_not": {
"term": {
"auditStatus": 5
}
}
}
}
}
环境搭建
- 官网下载最新版的Elasticsearch,依赖JDK,所以需要提前设置好JAVA的环境变量
- 运行 elasticsearch.bat,直接运行和在cmd命令框中运行是有区别的,后者能看到日志,前者可能会闪退
- 安装适配中文分词的分词器:ik分词器,版本需要和elasticsearch版本一致。
- 安装Head插件,进行集群和索引的管理。依赖node环境,所以要先安装node、grunt-cli
其他注意事项
- should与must的关系:且的关系(and),should数组元素之前是or的关系,通过minimum_should_match属性来指定最少满足should数组中的几个元素
- 数据量在亿级别,主分片一般8个、16个(通常为2的n次方),副本用1个(集群中写入文档的TPS与副本数量正相关,已1min写入1000个文档为例,副本为0,
则TPS为1000/60,副本为1,则TPS为2000/20) - 输出指定字段,通过setFetchSource来指定需要返回的字段
- 在7.X之后的版本,创建静态映射时,不需要再指定
type
,即没有了type的概念。
Specifying types in requests is deprecated. For instance, indexing a document no longer requires a document type. The new index APIs arePUT {index}/_doc/{id}
in case of explicit ids andPOST {index}/_doc
for auto-generated ids. Note that in 7.0, _doc is a permanent part of the path, and represents the endpoint name rather than the document type.
removal-of-types
来源:CSDN
作者:FollowYourHeart2015
链接:https://blog.csdn.net/MuErHuoXu/article/details/88645252