ElasticSearch基本操作

Elasticsearch是一个分布式的免费开源搜索和分析引擎,适用于包括文本、数字、地理空间、结构化和非结构化数据等在内的所有类型的数据。

ES安装

准备工作

安装es之前确保系统已安装JDK(需要JDK1.8以上版本)

安装及启动

下载es后,完成解压。解压完后的目录:

1
2
3
4
5
6
7
8
9
10
├─bin
├─config
├─jdk
├─lib
├─logs
├─modules
├─plugins
├─LICENSE.txt
├─NOTICE.txt
└─README.asciidoc

双击bin目录下的elasticsearch.bat即可启动es,默认启动后占用9200端口。

然后可通过http://127.0.0.1:9200/访问。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
name: "LSW",
cluster_name: "elasticsearch",
cluster_uuid: "DMAfqBqjSAm66iH6nGTeCg",
version: {
number: "7.10.0",
build_flavor: "default",
build_type: "zip",
build_hash: "51e9d6f22758d0374a0f3f5c6e8f3a7997850f96",
build_date: "2020-11-09T21:30:33.964949Z",
build_snapshot: false,
lucene_version: "8.7.0",
minimum_wire_compatibility_version: "6.8.0",
minimum_index_compatibility_version: "6.0.0-beta1"
},
tagline: "You Know, for Search"
}

version中的number即为版本号,这里是7.10.0。

安装ik分词器

在 es 目录中的 \plugins 目录下新建 ik 目录,然后将下载完成的 elasticsearch-analysis-ik 解压至此目录下。

完成后重启es,即可应用ik分词器。

安装可视化工具kibana

下载解压kibana,需修改kibana中config目录下的kibana.yml文件,添加安装的es地址,即:elasticsearch.url: "http://127.0.0.1:9200"

在bin目录下,双击kibana.bat,启动Kibana。

启动后,通过浏览器访问http://127.0.0.1:5601即可访问kibana。

通过侧边菜单【Dev Tools】进行执行命令

ES的基本概念

集群和节点

一个es集群是由一个或多和es节点组成的集合,每个节点都有自己的名字,如之前的master、slave1、slave2,节点是可以存储数据,参与索引数据等的独立服务。

索引(类似于数据库里面的database)

索引是含有相同属性的文档集合,索引在es中是通过一个名字来识别的,必须是英文字母小写,且不含中划线。

类型(相当于sql中的table)

一个索引可以定义一个或多个类型,文档必须属于一个类型。

文档(相当于sql中的一行记录)

文档是可以被索引的基本数据单位。

分片

每个索引都有多个分片,每个分片都是一个luncene索引。

分片的好处:分摊索引的搜索压力,分片还支持水平的拓展和拆分以及分布式的操作,可以提高搜索和其他处理的效率。

备份

拷贝一个分片就完成了分片的备份。

备份的好处:当主分片失败或者挂掉,备份就可以代替分片进行操作,进而提高了es的可用性,备份的分片还可以进行搜索操作,以分摊搜索的压力。

ES在创建索引时,默认创建5个分片,一份备份,可以修改,分片的数量只能在创建索引的时候指定,索引创建后就不能修改分片的数量了,而备份是可以动态修改的。

ES基本操作-Kibana-Dev Tools

GET /

在右侧将看到和启动完ES后在浏览器输入localhost:9200相同的内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"name" : "LSW",
"cluster_name" : "elasticsearch",
"cluster_uuid" : "DMAfqBqjSAm66iH6nGTeCg",
"version" : {
"number" : "7.10.0",
"build_flavor" : "default",
"build_type" : "zip",
"build_hash" : "51e9d6f22758d0374a0f3f5c6e8f3a7997850f96",
"build_date" : "2020-11-09T21:30:33.964949Z",
"build_snapshot" : false,
"lucene_version" : "8.7.0",
"minimum_wire_compatibility_version" : "6.8.0",
"minimum_index_compatibility_version" : "6.0.0-beta1"
},
"tagline" : "You Know, for Search"
}

创建索引

1
2
3
4
5
6
POST custinfo/_doc/1
{
"user":"zhangsan",
"age":18,
"city":"深圳"
}

说明:因为7版本之后,ES不再支持一个索引(index)可以创建多个类型(type),所以custinfo后边不再需要写入类型名称,而是统一使用_doc代替即可。

查看刚才创建的索引

1
GET custinfo/_doc/1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"_index" : "custinfo",
"_type" : "_doc",
"_id" : "1",
"_version" : 1,
"_seq_no" : 0,
"_primary_term" : 1,
"found" : true,
"_source" : {
"user" : "zhangsan",
"age" : 18,
"city" : "深圳"
}
}
  • _index是刚才创建的索引名称
  • _type是类型,7版本统一为_doc
  • _id为创建时的ID,如果创建索引的时候不设置ID,那么ES将默认分配一个ID
  • _version为版本号,如果我们之后对该数据进行了修改,那么他会随之变化
  • _source里边就是我们刚才加进去的数据内容

删除索引

1
DELETE custinfo

只需要在DELETE后边加上索引名称即可。

修改数据

1
2
3
4
5
6
7
POST custinfo/_doc/1
{
"user":"zhangsan",
"age":20,
"city":"上海",
"sex":"m"
}

这里我们修改了age、city值,并添加了一个新属性sex,执行之后我们再次执行获取数据内容命令GET custinfo/_doc/1,如下,可以看到数据已经被修改,版本号变成了2:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"_index" : "custinfo",
"_type" : "_doc",
"_id" : "1",
"_version" : 2,
"_seq_no" : 1,
"_primary_term" : 1,
"found" : true,
"_source" : {
"user" : "zhangsan",
"age" : 20,
"city" : "上海",
"sex" : "m"
}
}

bulk方法批量插入数据

使用POST方法,然后每一条数据的格式是一致的,首先第一行输入{"index":{"_index":"custinfo"}},也就是索引名称,第二行输入要插入的完整数据,这里特别提醒下,插入的这条数据不能使用刚才创建数据时的那种多行形式,只能使用没有回车的一条数据,否则会报错。

1
2
3
4
5
6
7
POST _bulk
{"index":{"_index":"custinfo"}}
{"user":"zhangsan","age":20,"city":"上海","sex":"m"}
{"index":{"_index":"custinfo"}}
{"user":"lisi","age":22,"city":"上海","sex":"m"}
{"index":{"_index":"custinfo"}}
{"user":"wangwu","age":22,"city":"深圳","sex":"f"}

执行完毕后,我们再次获取数据看一下:

1
GET custinfo/_search
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 4,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "custinfo",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"user" : "zhangsan",
"age" : 20,
"city" : "上海",
"sex" : "m"
}
},
{
"_index" : "custinfo",
"_type" : "_doc",
"_id" : "N0PxxnUBfXI6F1bGW_pJ",
"_score" : 1.0,
"_source" : {
"user" : "zhangsan",
"age" : 20,
"city" : "上海",
"sex" : "m"
}
},
{
"_index" : "custinfo",
"_type" : "_doc",
"_id" : "OEPxxnUBfXI6F1bGW_pJ",
"_score" : 1.0,
"_source" : {
"user" : "lisi",
"age" : 22,
"city" : "上海",
"sex" : "m"
}
},
{
"_index" : "custinfo",
"_type" : "_doc",
"_id" : "OUPxxnUBfXI6F1bGW_pJ",
"_score" : 1.0,
"_source" : {
"user" : "wangwu",
"age" : 22,
"city" : "深圳",
"sex" : "f"
}
}
]
}
}

按照条件查询

1
2
3
4
5
6
7
8
GET custinfo/_search
{
"query": {
"match": {
"city": "深圳"
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
{
"took" : 6,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 2.4079456,
"hits" : [
{
"_index" : "custinfo",
"_type" : "_doc",
"_id" : "OUPxxnUBfXI6F1bGW_pJ",
"_score" : 2.4079456,
"_source" : {
"user" : "wangwu",
"age" : 22,
"city" : "深圳",
"sex" : "f"
}
}
]
}
}

当同一个属性满足逻辑或时的查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
GET custinfo/_search
{
"query": {
"bool": {
"should": [
{
"match": {
"city": "深圳"
}
},
{
"match": {
"city": "上海"
}
}
]
}
}
}

这里是查询属性city等于上海或者深圳的数据,其中,固定输入”query”,固定输入”bool”,输入为”should”,表示是逻辑或的关系。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 4,
"relation" : "eq"
},
"max_score" : 2.4079456,
"hits" : [
{
"_index" : "custinfo",
"_type" : "_doc",
"_id" : "OUPxxnUBfXI6F1bGW_pJ",
"_score" : 2.4079456,
"_source" : {
"user" : "wangwu",
"age" : 22,
"city" : "深圳",
"sex" : "f"
}
},
{
"_index" : "custinfo",
"_type" : "_doc",
"_id" : "1",
"_score" : 0.7133499,
"_source" : {
"user" : "zhangsan",
"age" : 20,
"city" : "上海",
"sex" : "m"
}
},
{
"_index" : "custinfo",
"_type" : "_doc",
"_id" : "N0PxxnUBfXI6F1bGW_pJ",
"_score" : 0.7133499,
"_source" : {
"user" : "zhangsan",
"age" : 20,
"city" : "上海",
"sex" : "m"
}
},
{
"_index" : "custinfo",
"_type" : "_doc",
"_id" : "OEPxxnUBfXI6F1bGW_pJ",
"_score" : 0.7133499,
"_source" : {
"user" : "lisi",
"age" : 22,
"city" : "上海",
"sex" : "m"
}
}
]
}
}

多条件查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
GET custinfo/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"age": "22"
}
},
{
"match": {
"city": "上海"
}
}
]
}
}
}

这里和上一条查询的关键区别就在于由”should”改为”must”。

范围查询并进行排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
GET custinfo/_search
{
"query": {
"range": {
"age": {
"gte": 20,
"lte": 21
}
}
},
"sort": [
{
"age": {
"order": "desc"
}
}
]
}

这里,”gte”和”lte”表示查询属性”age”在20-21范围的数据,然后sort表示排序,排序的属性是”age”,“order”表示排序为倒序”desc”。

聚合查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
GET custinfo/_search
{
"size": 0,
"aggs": {
"age": {
"range": {
"field": "age",
"ranges": [
{
"from": 20,
"to": 21
},{
"from": 22,
"to": 25
},{
"from": 25,
"to": 30
}
]
}
}
}
}

这条请求实现的是统计属性”age”按照20-21,22-25,25-30划分的数据条数分别为多少。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
{
"took" : 8,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 4,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
},
"aggregations" : {
"age" : {
"buckets" : [
{
"key" : "20.0-21.0",
"from" : 20.0,
"to" : 21.0,
"doc_count" : 2
},
{
"key" : "22.0-25.0",
"from" : 22.0,
"to" : 25.0,
"doc_count" : 2
},
{
"key" : "25.0-30.0",
"from" : 25.0,
"to" : 30.0,
"doc_count" : 0
}
]
}
}
}

参考


----------- 本文结束啦感谢您阅读 -----------

赞赏一杯咖啡

欢迎关注我的其它发布渠道