Elasticsearch 常用操作(ES-6.4)

文章目录

    • 一、基本操作
      • 查询索引的基本信息
      • 索引的相关操作
      • 文档相关操作
        • 1.单个文档增删改查
        • 2.批量处理
    • 二、深入探索
      • 搜索的分类
      • 1. 查询所有并排序
      • 2. 分页查询 (查询第2页的用户(每页显示2条))
      • 3. 基于全文检索的查询(分析检索关键词 匹配索引库 返回结果)
      • 4. 基于Term词元查询
      • 5. 基于range范围查询
      • 6. 基于前缀(prefix)查询
      • 7. 基于通配符(wildcard)的查询 ? 匹配一个字符 * 匹配0~n个字符
      • 8. 基于 Id[] 的查询
      • 9. 基于 Fuzzy 的查询
      • 10. 基于Boolean的查询(多条件查询)
    • 三、过滤器
      • 使用过滤器示例
      • 1. term 、 terms Filter
      • 2. ranage filter
      • 3. exists filter
      • 4.ids filter
    • 四、聚合(Aggregations)
      • 1. 度量(metric)聚合
        • 平均值聚合
        • 最大(小)值聚合
        • 相加之和的聚合
        • 以上四种聚合的打包查询
      • 2.桶(bucketing)聚合
        • 自定义区间范围的聚合
        • 自定义分组依据Term(不能选择text类型的field)
        • 时间区间聚合(Date Range Aggregation)
        • 直方图聚合(Histogram Aggregation)
        • 日期直方图聚合(Date Histogram Aggregation)
        • 两种聚合嵌套使用

以下操作均为在 kibana 中的测试操作, postman 请手动加上ip和port

一、基本操作

查询索引的基本信息

	#查询索引健康状态
GET /_cat/health?v

	#查看每个操作返回结果字段的意义
GET /_cat/health?help

	#查看集群中节点信息
GET /_cat/nodes?v

	#查看集群中的索引信息
GET /_cat/indices?v

	#简化写法
GET /_cat/indices?v&h=health,status,index

索引的相关操作

	#创建索引
PUT /xiaobai

	#删除索引
DELETE /xiaobai

	#使用这种方式创建mapping,索引名在节点中必须不存在
	#创建类型 mapping
PUT /xiaobai/user
{
  "mappings": {
    "user":{
      "properties":{
        "name":{"type":"text"},
        "age":{"type":"integer"},
        "birth":{"type":"date"}
      }
    }
  }
}
	# 创建index(xiaobai)后,在指定index中添加类型mapping(user)
POST /xiaobai/user
{
  "user": {
    "properties": {
      "id": { "type": "text" },
      "name": { "type": "text" },
      "age": { "type": "integer" }, 
      "created": {
        "type": "date",
        "format": "strict_date_optional_time||epoch_millis"
          }
      }
  }
}

	#查看类型mapping  # 语法:GET /索引名/_mapping/类型名
GET /xiaobai/_mapping/user

文档相关操作

1.单个文档增删改查

	#新增单个文档    语法: PUTPOST/索引名/类型名/id
PUT /xiaobai/user/1
{
  "name":"张三",
  "age":18,
  "created":"2018-01-01"
}
	#或
POST /xiaobai/user
{                   # 在不指定id的情况下  ES默认生成一个不重复的id
  "name":"李四",
  "age":20,
  "created":"2018-01-02"
}

	#根据id查询单个 
GET /xiaobai/user/rMtpDmgBfCGt9hTRaYyW
GET /xiaobai/user/1

	#修改单个  这样做是直接替换  而不是动态修改(只修改指定的field)
PUT /xiaobai/user/q8toDmgBfCGt9hTROIxL
{
  "doc":{
    "name":"李大侠",
    "age":21
  }
}
	#实现动态修改
POST /xiaobai/user/rMtpDmgBfCGt9hTRaYyW/_update
{
  "doc": {
    "name":"李小侠1"
  }
}

	#删除单个
DELETE /xiaobai/user/1
DELETE /xiaobai/user/q8toDmgBfCGt9hTROIxL

2.批量处理

	#批量添加
POST /xiaobai/user/_bulk
{"index":{}}
{"name":"王五","age":21,"created":"2018-01-03"}
{"index":{}}
{"name":"赵六","age":22,"created":"2018-01-04"}
GET /xiaobai/user/rstvDmgBfCGt9hTR14ws

	#批量操作(删除+修改)
POST /xiaobai/user/_bulk
{"update":{"_id":"rstvDmgBfCGt9hTR14ws"}}
{"doc":{"name":"啦啦啦"}}
{"delete":{"_id":"1"}}

二、深入探索

探索之前的准备:

创建zpark索引

PUT /xiaobai
{
  "mappings": {
    "user":{
      "properties":{
        "name":{"type":"text"},
        "realname":{"type":"text"},
        "age":{"type":"integer"},
        "birthday":{"type":"date"},
        "salary":{"type":"double"},
        "address":{"type":"text"}
      }
    }
  }
}

批量插入测试数据

POST /xiaobai/user/_bulk

{"index":{"_id":1}}
{"name":"zs","realname":"张三","age":18,"birthday":"2018-12-07","salary":1000.0,"address":"北京市昌平区沙阳路55号"}

{"index":{"_id":2}}
{"name":"ls","realname":"李四","age":20,"birthday":"2017-10-10","salary":5000.0,"address":"北京市朝阳区三里屯街道21号"}

{"index":{"_id":3}}
{"name":"ww","realname":"王五","age":25,"birthday":"2016-03-15","salary":4300.0,"address":"北京市海淀区中关村大街新中关商城2楼511室"}

{"index":{"_id":4}}
{"name":"zl","realname":"赵六","age":20,"birthday":"2003-04-20","salary":12300.0,"address":"北京市海淀区中关村软件园9号楼211室"}

{"index":{"_id":5}}
{"name":"tq","realname":"田七","age":35,"birthday":"2001-08-11","salary":1403.0,"address":"北京市海淀区西二旗地铁辉煌国际大厦负一楼"}

搜索的分类

搜索有两种方式:一种是通过 URL 参数进行搜索,另一种是通过 DSL(Request Body) 进行搜索

​ DSL:Domain Specified Language,特定领域语言
使用请求体可以让你的JSON数据以一种更加可读和更加富有展现力的方式发送。

1. 查询所有并排序

    ### URL实现

    #### q=* 查询所有字段  
    #### sort=age:desc 根据age字段降序(desc)排序
GET /xiaobai/user/_search?q=*&sort=age:desc&pretty

    ### DSL实现
    #### "match_all":{} 查询所有
    #### "age":"desc" 年龄降序

GET /xiaobai/user/_search
{
 "query":{
  "match_all":{} 
 },
 "sort":{
   "age":"desc"  
 }
}

2. 分页查询 (查询第2页的用户(每页显示2条))

    ### URL实现
    #### from=2&size=2 从第二条开始查询两条数据
GET /xiaobai/user/_search?q=*&sort=_id:asc&from=2&size=2

    ### DSL实现
    #### "from":2, 从第2条开始  检索
    #### "size":2  查出2GET /xiaobai/user/_search
{
 "query":{
  "match_all":{}
},
 "sort":{
   "_id":"asc" 
 },
 "from":1, 
 "size":3  
}

3. 基于全文检索的查询(分析检索关键词 匹配索引库 返回结果)

    ### 需求: 查询 address 在海淀区的所有用户,并高亮
    ### DSL实现
GET /xiaobai/user/_search
{
 "query": {
  "match": {
   "address":"海淀区"
 }
},
 "highlight": {
  "fields": { 
   "address": {} 
   }
 }
}

4. 基于Term词元查询

    ###需求 :  查询 name 是 zs 关键字的用户

    ###  URL实现
GET /xiaobai/user/_search?q=name:zs
    ###  DSL实现
GET /xiaobai/user/_search
{
 "query":{
  "term": {
   "name": {
    "value": "zs"
   }
  }
 }
}	

5. 基于range范围查询

###需求 : 查询年龄在 20~30 岁之间的用户

###  DSL实现
GET /xiaobai/user/_search
{
 "query": {
  "range": {
   "age": {
    "gte": 20,
    "lte": 30
   }
  }
 }
}

6. 基于前缀(prefix)查询

### 需求:查询真实姓名以 李 开头的用户

### DSL实现
GET /xiaobai/user/_search
{
 "query": {
  "prefix": {
   "realname": {
    "value": "李"
   }
  }
 }
}


7. 基于通配符(wildcard)的查询 ? 匹配一个字符 * 匹配0~n个字符

### 需求:查询名字以 s 结尾的用户
### URL实现
GET /xiaobai/user/_search?q=name:*s  查询名字以 s 结尾的用户
GET /xiaobai/user/_search?q=name:z*  查询名字以 z 开头的用户

###DSL实现
GET /xiaobai/user/_search
{
 "query": {
  "wildcard": {
    "name": {
      "value": "*s"
      }
    }
  }
}

8. 基于 Id[] 的查询

    ###	 需求: 查询 id 为123的用户 

    ### DSL实现
GET /xiaobai/user/_search
{
  "query": {
    "ids": {
      "values": [1,2,3]
    }
  }
}	

9. 基于 Fuzzy 的查询

###需求:模糊查询 realname 中包含 张 关键字的用户

### DSL实现
GET /xiaobai/user/_search
{
  "query": {
    "fuzzy": {
      "realname": {"value": "张"}
    }
  }
}

10. 基于Boolean的查询(多条件查询)

must :查询结果必须符合该查询条件(列表)。
should :类似于or的查询条件。
must_not :查询结果必须不符合查询条件(列表)。

### 需求:查询 age 在15-30岁之间并且 name 必须通配z*

### DSL实现
GET /xiaobai/user/_search
{
  "query": {
    "bool": {
        "must": [ 
        {
          "range": {
            "age": {
              "gte": 15,
              "lte": 30
            }
          }
        },
        {
          "wildcard": {
            "name": {
              "value": "z*"
            }
          }
        }
      ],
      "must_not": [ 
        {
          "regexp": {
            "name": ".*s"
          }
        }
      ]
    }
  }   
}

三、过滤器

​ 其实准确来说,ES中的查询操作分为2种:查询(query)和过滤(filter)查询即是之前提到的query查询,它(查询)默认会计算每个返回文档的得分,然后根据得分排序。而**过滤(filter)**只会筛选出符合的文档,并不计算得分,且它可以缓存文档。所以,单从性能考虑,过滤比查询更快。

​ 换句话说,过滤适合在大范围筛选数据,而查询则适合精确匹配数据。一般应用时,应先使用过滤操作过滤数据,然后使用查询匹配数据。

使用过滤器示例

GET /xiaobai/user/_search
{
  "query":{
    "bool": {
      "must": [
        {"match_all": {}}
      ],
      "filter": { # 过滤年龄大于等于25岁的用户
      "range": {
        "age": {
          "gte": 25
          }
        }
      }
    }
  }
}

1. term 、 terms Filter

term、terms的含义与查询时一致。term用于精确匹配、terms用于多词条匹配

GET /xiaobai/user/_search
{
  "query":{
    "bool": {
      "must": [
        {"match_all": {}}
      ],
      "filter": {
        "terms": {
          "name": ["zs","ls"]
        }
      }
    }
  }
}

2. ranage filter

见示例

3. exists filter

exists 过滤指定字段没有值的文档

GET /xiaobai/user/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match_all": {}
        }
      ],
      "filter": {
        #
      排除salary为null的结果
      "exists": {
        "field": "salary"
        }
      }
    }
  }, 
  "sort": [
    {"_id": {"order": "asc"}}
  ]
}
==========所有薪水为空的数据====
GET /xiaobai/user/_search
{
  "query": {
    "bool": {
      "must_not": [
        {
          "exists": {
            "field": "salary"
          }
        }
      ]
    }
  }
}

4.ids filter

需要过滤出若干指定_id的文档,可使用标识符过滤器(ids)

GET /xiaobai/user/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "address": "昌平区"
          }
        }
      ],
      "filter": {
        "ids": {  # id 过滤器
        "values": [1,2,3]
        }
      }
    }
  }
}

四、聚合(Aggregations)

​ 聚合提供了功能可以分组并统计你的数据。理解聚合最简单的方式就是可以把它粗略的看做SQL的GROUP BY操作和SQL的聚合函数。
ES中常用的聚合:
metric(度量)聚合:度量类型聚合主要针对的number类型的数据,需要ES做比较多的计算工作
bucketing(桶)聚合:划分不同的“桶”,将数据分配到不同的“桶”里。非常类似sql中的group语句的含义

ES中的聚合API(格式)如下:

"aggregations" : {          // 表示聚合操作,可以使用aggs替代
  "" : {  // 聚合名,可以是任意的字符串。用做响应的key,便于快速取得正确的响应数据。
    "" : {   // 聚合类别,就是各种类型的聚合,如min等
      <aggregation_body>    // 聚合体,不同的聚合有不同的body
   }
   [,"aggregations" : { [<sub_aggregation>]+ } ]? // 嵌套的子聚合,可以有0或多个
 }
 [,"" : { ... } ]* // 另外的聚合,可以有0或多个
}

1. 度量(metric)聚合

平均值聚合

# Avg Aggregation  平均值查询,作用于number类型字段上。如:查询用户的平均年龄
POST /xiaobai/user/_search
{
    "aggs":{
        "age-avg":{
                "avg":{
                    "field":"age"
                }
        }
    }
}

## 可以先进行过滤查询,在进行平均值聚合
POST /xiaobai/user/_search
{
    "query":{
        "ids":{
            "values":[1,2,3]
        }
    },
    "aggs":{
        "age-avg":{    # 给查询结果命名  随意
                "avg":{
                    "field":"age"
                }
        }       
     }
}

最大(小)值聚合

# Max Aggregation  最大值查询。如:查询员工的最高工资
POST/xiaobai/user/_search
{
    "aggs":{
        "salary-max":{    # 给查询结果命名  随意
            "max":{
				"field":"salary"
            }
        }
    }
}

# Min Aggregation  最小值查询。如:查询员工的最低工资
POST/xiaobai/user/_search
{
    "aggs":{
        "salary-min":{    # 给查询结果命名  随意
            "min":{
				"field":"salary"
            }
        }
    }
}

相加之和的聚合

# Sum Aggregation  相加之和的查询。如:查询员工工资之和
POST/xiaobai/user/_search
{
    "aggs":{
        "salary-sum":{    # 给查询结果命名  随意
            "sum":{
				"field":"salary"
            }
        }
    }
}

以上四种聚合的打包查询

#  Stats Aggregation  统计查询,一次性统计出某个字段上的常用统计值
POST/xiaobai/user/_search
{
    "aggs":{
        "age-stats":{
            "stats":{
                "field":"age"
            }
        }
    }
}

2.桶(bucketing)聚合

自定义区间范围的聚合

# Range Aggregation 自定义区间范围的聚合  我们可以自己手动地划分区间,ES会根据划分出来的区间将数据分配不同的区间上去。
#  如: 统计0-20岁,20-35岁,35~60岁用户人数
POST /xiaobai/user/_search
{
    "aggs":{
        "age-range":{
            "range":{
                "field":"age",
                "ranges":[
                    {
                        "from":0,
                        "to":20
                    },{
                        "from":20,
                        "to":35
                    },{
                        "from":35,
                        "to":60
                    }
                ]
            }
        }
    }
}

自定义分组依据Term(不能选择text类型的field)

# Terms Aggregation 自定义分组依据Term,对分组后的数据进行统计
# 如:根据年龄分组,统计相同年龄的用户
POST /xiaobai/user/_search
{
    "aggs":{
        "age-terms":{
            "terms":{
                "field":"age",  # 这里的域的类型不能为text,否则报错
                 "size":3   # 查询三条
            }
        }
    }
}

时间区间聚合(Date Range Aggregation)

# 时间区间聚合专门针对date类型的字段,它与Range Aggregation的主要区别是其可以使用时间运算表达式。
#	now+10y:表示从现在开始的第10年。
#	now+10M:表示从现在开始的第10个月。
#	1990-01-10||+20y:表示从1990-01-01开始后的第20年,即2010-01-01。
#	now/y:表示在年位上做舍入运算。
#如: 统计生日在2019年、2018年、2017年的用户
POST /xiaobai/user/_search
{
    "aggs":{
        "birthday-dra":{
            "date_range":{
                "field":"birthday",
                "format":"yyyy-mm-dd",
                "ranges":[
                    {
                        "from":"now/y",  #今年(2019)的11"to":"now"		#当前的时间	   从今年元旦至今
                    }{
                    	"from":"now/y-1y", # 去年(2018)的11"to":"now/y"       # 当年的11日   去年元旦到今年元旦
                    }{
                    	"from":"now/y-1y", # 前年(2017)的11"to":"now/y"       # 去年的11日   去年元旦到今年元旦
                    }
                ]     
            }
        }
    }
}

直方图聚合(Histogram Aggregation)

# Histogram Aggregation 
#	直方图聚合,它将某个number类型字段等分成n份,统计落在每一个区间内的记录数。它与前面介绍的Range聚合
# 非常像,只不过Range可以任意划分区间,而Histogram做等间距划分。既然是等间距划分,那么参数里面必然有距
# 离参数,就是interval参数。

#根据年龄间隔(5岁)统计
POST /xiaobai/user/_search
{
    "aggs":{
        "age-his":{
            "histogram":{
                "field":"age",
                "interval":5    # 间隔5
            }
        }
    }
}

日期直方图聚合(Date Histogram Aggregation)

#	日期直方图聚合,专门对时间类型的字段做直方图聚合。这种需求是比较常用见得的,我们在统计时,通常就会按
# 照固定的时间断(1个月或1年等)来做统计。
#  如:按年统计用户
POST /xiaobai/user/_search
{
    "aggs":{
        "birthday-dha":{
            "date_histogram":{
                "field":"birthday",
                "interval":"year",
                "format":"yyyy-mm-dd"
            }
        }
    }
}

两种聚合嵌套使用

#	聚合操作是可以嵌套使用的。通过嵌套,可以使得metric类型的聚合操作作用在每一bucket上。我们可以使用ES的嵌套聚合操作来完成稍微复杂一点的统计功能。
#  如:统计每年中用户的最高工资
POST /xiaobai/user/_search
{
    "aggs":{
        "birthday-dha":{
            "date_histogram":{
                "field":"birthday",
                "interval":"year",
                "format":"yyyy-mm-dd"  
            }
        },"max-salary":{
            "max":{
                "field":"salary"
            }
        }
    }
}

你可能感兴趣的:(ElasticSearch)