ElasticSearch入门教程

ElasticSearch入门教程

ES 基本概念

Cluster: 集群

Node: 节点

Shard: 分片

Replia: 副本

全文检索

MySQL ElasticSearch
Database Index
Table Type
Row Document
Column Field
Schema Mapping
Index Everything is indexed
SQL Query DSL
SELECT * FROM table GET
UPDATE table SET PUT

ELK

ELK = ElasticSearch + Logstash + Kibana

ES特点和优势

  1. 分布式实时文件存储,可将每一个字段存入索引,使其可以被检索到
  2. 实时分析的分布式搜索引擎
    分布式:索引分拆成多个分片,每个分片可有零个或多个副本。集群中的每个数据节点都可承载一个或多个分片,并且协调和处理各种操作。
  3. 可以扩展到上百台服务器,处理PB级别的结构化或非结构化数据
  4. 支持插件机制,分词插件,同步插件,Hadoop 插件,可视化插件。

Linux 下安装ElasticSearch

  1. 下载 ElasticSearch

  2. 安装 ElasticSearch

    1
    tar -zxvf elasticsearch-2.3.3.tar.gz
  3. 启动

    1
    ./elasticsearch

查看信息

1
curl -X GET 'http://localhost:9200'

elasticsearch 外网访问

1
2
3
# 修改配置文件 config/elasticsearch.yml

network.host: 0.0.0.0

安装注意点

  1. ElasticSearch 不能使用root帐号启动
  2. 服务器 /etc/sysctl.conf 配置信息 vm.max_map_count = 655360 ,重启命令 sysctl -p
  3. 服务器ulimit -a 查看文件数,配置文件位置/etc/security/limits.conf,修改之后退出当前用户,或者重新登录。
    1
    [1]: max number of threads [1024] for user [sgm] is too low, increase to at least [4096]

###下载安装插件

安装分词插件

1
./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v5.5.1/elasticsearch-analysis-ik-5.5.1.zip
1
./plugin install mobz/elasticsearch-head

基本概念

Node 与 Cluster

Elastic本质是一个分布式数据库,允许多台服务器协同工作,每台服务器可以运行多个Elastic实例。

单个Elastic实例称为一个节点(node).一组节点构成一个集群(cluster)。

Index

Elastic会索引所有字段,经过处理后写入一个反向索引(Inverted Index)。查找数据的时候,直接查找该索引。

Elastic数据管理的顶层单位就叫做Index(索引)。它是单个数据库的同义词。每个Index(即数据库)的名字必须是小写。

查看当前节点的所有Index

1
curl -X GET 'uri/_cat/indices?v'

Document

Index 里面单条的记录称为Docuemnt(文档)。许多条Document构成一个Index。

同一个Index里面的Document不要求相同的结构(scheme),但是最好能保持相同,这样有利于提高搜索效率。

Type

Document 可以分组,比如 weather 这个Index里面,可以按城市分组(北京和上海),也可以按气候分组(晴天和雨天)。这种分组就叫做Type,它是虚拟的逻辑分组,用来过滤Document。

不同的Type应该有相似的结构(Schema),举例来说,id字段不能在这个组是字符串,在另一个组是数值。这是与关系型数据库的表的一个区别。性质完全不同的数据(比如products 和 logs)应该存成两个Index,而不是一个Index里面的两个Type

列出每个Index所包含的Type

1
localhost:9200/_mapping?pretty=true

Tip:Elastic 6.x 版只允许每个Index包含一个Type,7.x 版将会彻底移除Type。

新建和删除Index

新建Index,可以直接想Elastic服务器发出PUT请求。
新建一个名叫weather的Index

1
curl -X PUT 'localhost:9200/weather'

发出 Delete 请求删除这个Index

1
curl -X DELETE 'localhost:9200/weather'

中文分词

凡是需要搜索的中文字段,都需要单独设置

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
curl -X PUT 'url' -d '
{
"mappings":{
"person":{
"properties": {
"user": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_max_word"
},
"title": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_max_word"
},
"desc": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_max_word"
}
}
}
}
}
'

上面代码中, analyzer是字段文本的分词器,search_analyzer是搜索词的分词器。ik_max_word分词器是插件ik提供的,可以对文本进行最大数量的分词。

数据操作

向指定的 /Index/Type 发送PUT请求,就可以在Index里面新增一条记录。
例如:

1
2
3
4
5
6
7
curl -X PUT 'localhost:9200/accounts/persion/1' -d '
{
"user": "张三",
"title": "工程师",
"desc": "数据库管理"
}
'

服务器返回的JSON对象,会给出Index,Type,Id,Version等信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"_index": "accounts",
"_type": "person",
"_id": "1",
"_version": "1",
"result": "create",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"created": true
}

上代码插入的请求路径是/accounts/person/1,最后的 1是改条记录的Id。它不一定是数字,任意字符串(比如 abc) 都可以。

新增记录的时候,也可以不指定Id,这时要改成POST 请求。

1
2
3
4
5
6
7
curl -X POST 'localhost:9200/accounts/person' -d '
{
"user": "李四",
"title": "工程师",
"desc": "系统管理"
}
'

通过POST发出一个请求,添加一条记录,这时服务器返回的JSON对象里面,_id 字段就是一个随机字符串。

查看记录

/Index/Type/Id 发出GET请求,就可以查看这条记录。

1
curl 'localhost:9200'/accounts/person/1?pretty=true'

请求查看/accounts/persopn/1这条记录,URL的参数 pretty=true表示以易读的格式返回。
返回的数据中,found字段表示查询成功,_source字段返回原始记录。

1
2
3
4
5
6
7
8
9
10
11
12
{
"_index": "accounts",
"_type": "person",
"_id": "1",
"_version": 1,
"found": true,
"_source":{
"user":"",
"title": "",
"desc": ""
}
}

如果Id不正确,就查不到数据,found字段就是false

删除记录

删除记录就是发出DELETE请求

1
curl -X DELETE 'localhost:9200/accounts/person/1'

更新数据

更新记录就是使用PUT请求,重新发送一次数据。

1
2
3
4
5
curl -X PUT 'localhost:9200/accounts/person/1' -d '{
"user": "张三",
"title": "工程师",
"desc": "数据库管理,软件开发"
}'

返回信息

1
2
3
4
5
6
7
8
9
{
"_index": "accounts",
"_type": "person",
"_id": "1",
"_version": 2,
"result": "updated",
"_shards": {"total":2,"successful":1,"failed":0},
"created": false
}

从上面的记录可以看到,记录的Id没变,但是版本(version)从1变成了2,操作类型(result)从created变成updated,created字段变成false,因为这次不是新建记录。

数据查询

返回所有记录

使用GET方法,直接请求/Index/Type/_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
curl 'localhost:9200/accounts/person/_search'

{
"took": 2,
"timed_out": false,
"_shards": {"total":5,"successful":5,"failed":0},
"hits":{
"total":2,
"max_score": 1.0,
"hits":{
{
"_index": "accounts",
"_type": "person",
"_id": "xxxx",
"_score": 1.0,
"_source": {
"user":"",
"title":"",
"desc": ""
}
}
}
}
}

上面代码中,返回结果的took字段表示改操作的耗时(单位是毫秒),timed_out字段表示是否超时,hits字段表示命中的记录,里面子字段的含义如下

1
2
3
total 返回记录数
max_score 最高的匹配程度
hits 返回的记录组成的数组

返回的记录中,每条记录都有一个_score字段,表示匹配的程序,默认是按照这个字段降序排列。

全文搜索

Elastic的查询非常特别,使用自己的查询语法,要求GET请求带有数据体。

1
2
3
4
5
curl 'localhost:9200/accounts/person/_search' -d '
{
"query": {"match": {"desc": "软件"}}
}
'

上面代码使用Match 查询,指定的匹配条件是desc字段里面包含”软件”这个词。返回结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
{
"took": 3,
"time_out": false,
"_shards": {"total":5,"successful":5,"failed":0},
"hits":{
"total": 1,
"max_score": "0.2858",
"hits":[
{}
]
}
}

Elastic默认一次返回10条结果,可以通过size字段改变这个设置。

1
2
3
4
5
6
curl 'localhost:9200/accounts/person/_search' -d '
{
"query": {"match": {"desc":"管理"}},
"size": 1
}
'

上面的代码指定,每次只返回一条结果。

还可以通过from字段,指定位移。

1
2
3
4
5
curl 'localhost:9200/accounts/person/_search' -d '{
"query": {"match": {"desc":"管理"}},
"from": 1,
"size": 1
}'

上面代码指定,从位置1开始(默认是从位置0开始),只返回一条结果。

逻辑运算

如果有多个搜索关键字,Elastic认为它们是or关系。

1
2
3
4
5
curl 'localhost:9200/accounts/person/_search' -d '
{
"query":{"match": {"desc": "系统 软件"}}
}
'

上面的代码搜索的是软件 or 系统
如果要执行多个关键字词的and搜索,必须使用布尔查询。

1
2
3
4
5
6
7
8
9
10
11
12
curl 'localhost:9200/accounts/person/_search' -d '
{
"query": {
"bool":{
"must":[
{"match": {"desc": "软件"}},
{"match": {"desc": "系统"}}
]
}
}
}
'

REST API

ES 学习
ES 学习

ES 在Java 中的使用