0%

Elasticsearch 入门

Elasticsearch 是一个分布式的RESTful风格的搜索和数据分析工具,是当前流行的企业级搜索引擎。

基本概念

Cluster

集群通过独一无二的名称来进行区分,每个集群是由一个或者多个Node组成。不能在不同的环境中使用相同的cluster名,否则node可能错误地划分到某个cluster中。

Node

作为集群(cluster)的一部分,存储数据。

Index

索引是某些具有相同特征的文档的集合,可以对于不同的数据来建立不同的索引。当进行创建索引、搜索、更新和删除等操作时,需要通过该索引名来访问其对应的文件。

Document

一个Document是可以被索引的最小单元,不同的Document可以对应不同的数据,例如客户信息,产品信息等等。

Shards & Replicas

考虑到一个index可能存储大量的数据以至于超出硬件的限制,因此Elasticsearch可以将一个index划分为多个块称为shards,每个shards可以看做是一个独立的index。通过Shards的机制,一方面可以用于将数据进行分片;另一方面也可以将数据通过不同的Shards进行分发,进而提升了输入输出的性能。

另外为了防止网络等原因导致的某个Shards/Node无法正常工作,Elasticsearch中可以通过生成一个或多个Shards的副本,来保证可靠性,这些副本称为replica shards,或者简称replicas。

安装

1
2
3
4
curl -L -O https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.3.2.tar.gz
tar -xvf elasticsearch-6.3.2.tar.gz
cd elasticsearch-6.3.2/bin
./elasticsearch

基本操作

  • 集群健康状况
1
GET /_cat/health?v
  • 获取集群节点
1
GET /_cat/nodes?v
  • 获取索引信息
1
GET /_cat/indices?v
  • 创建索引
1
2
PUT /customer?pretty
GET /_cat/indices?v

第一句通过PUT操作在集群中创建一个customer的索引,末尾加上pretty表示pretty-print该操作返回的jason数据。

  • 索引和查找数据
1
2
3
4
PUT /customer/_doc/1?pretty
{
"name": "John Doe"
}

上面这条指令将一个简单的文档加入到customer索引中,并且id为1。可以通过id来查找刚索引好的数据,具体指令如下:

1
2
3
4
5
6
7
8
{
"_index" : "customer",
"_type" : "_doc",
"_id" : "1",
"_version" : 1,
"found" : true,
"_source" : { "name": "John Doe" }
}
  • 删除索引
1
DELETE /customer?pretty

通过上述简单的指令可以看到,我们可以使用比较固定的模式<REST Verb> /<Index>/<Type>/<ID>从Elasticsearch获取数据。

修改数据

索引/替换数据

索引数据

1
2
3
4
PUT /customer/_doc/1?pretty
{
"name": "John Doe"
}

在索引数据时,ID这一项是可选的。如果不指定ID,Elasticsearch会生成一个随机的ID来索引数据,这个ID也会在索引完成后返回在结果中。

替换数据

在索引了一条数据之后,再使用相同的ID来索引一条数据,新的数据将会替换掉之前索引的数据。

1
2
3
4
PUT /customer/_doc/1?pretty
{
"name": "Jane Doe"
}

更新数据

我们可以使用下面的指令来更新之前例子中插入的数据。

1
2
3
4
POST /customer/_doc/1/_update?pretty
{
"doc": { "name": "Jane Doe", "age": 20 }
}

除此之外,也可以通过简单的script来更新数据,

1
2
3
4
POST /customer/_doc/1/_update?pretty
{
"script" : "ctx._source.age += 5"
}

ctx._source表示将被更新的文档。

删除数据

下面的语句将会删除ID为2的数据

1
DELETE /customer/_doc/2?pretty

批量操作

除了上述对数据进行分开操作以外,Elasticsearch也提供了_bulkAPI来进行批量操作,如下的例子中将会首先更新ID为1对应的文档,另外删除ID为2对应的文档。

1
2
3
4
POST /customer/_doc/_bulk?pretty
{"update":{"_id":"1"}}
{"doc": { "name": "John Doe becomes Jane Doe" } }
{"delete":{"_id":"2"}}

搜索数据

在介绍搜索数据的API之前,你可以参考官方教程来索引部分数据。

搜索API

  • 使用类似于如下例子的REST request URI来进行搜索。
1
GET /bank/_search?q=*&sort=account_number:asc&pretty

注意到搜索时都需要使用到_search这个endpoint,bank为索引名。q=*表示匹配该索引下的所有文档。sort=account_number表示将返回的结果按照account_number来进行升序排列。同样的pretty表示将返回的结果pretty-print。

  • 使用request body如下,可以达到同样的效果
1
2
3
4
5
6
7
GET /bank/_search
{
"query": { "match_all": {} },
"sort": [
{ "account_number": "asc" }
]
}

Request Body语法

  • 限制返回结果数目
1
2
3
4
5
GET /bank/_search
{
"query": { "match_all": {} },
"size": 1
}
  • 限制查找范围,如下例子返回10-19之间的文档
1
2
3
4
5
6
GET /bank/_search
{
"query": { "match_all": {} },
"from": 10,
"size": 10
}
  • 对返回值进行排序
1
2
3
4
5
GET /bank/_search
{
"query": { "match_all": {} },
"sort": { "balance": { "order": "desc" } }
}
  • 限制返回的列
1
2
3
4
5
GET /bank/_search
{
"query": { "match_all": {} },
"_source": ["account_number", "balance"]
}
  • 匹配某个字段,注意matchmatch_phrase的区别
1
2
3
4
5
GET /bank/_search
{
"query": { "match": { "address": "mill lane" } } # 包含mill或者lane
"query": { "match_phrase": { "address": "mill lane" } } # 包含mill lane
}
  • 组合多个匹配条件,must表示必须匹配两个条件,如果改成should则为两个条件之一满足即可,must_not则为两个条件均不匹配。
1
2
3
4
5
6
7
8
9
10
11
GET /bank/_search
{
"query": {
"bool": {
"must": [
{ "match": { "address": "mill" } },
{ "match": { "address": "lane" } }
]
}
}
}
  • 组合多个匹配语句
1
2
3
4
5
6
7
8
9
10
11
12
13
GET /bank/_search
{
"query": {
"bool": {
"must": [
{ "match": { "age": "40" } }
],
"must_not": [
{ "match": { "state": "ID" } }
]
}
}
}
  • 过滤结果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
GET /bank/_search
{
"query": {
"bool": {
"must": { "match_all": {} },
"filter": {
"range": {
"balance": {
"gte": 20000,
"lte": 30000
}
}
}
}
}
}
  • 聚合数据,类似于sql语句中的group by等语句
1
2
3
4
5
6
7
8
9
10
11
GET /bank/_search
{
"size": 0,
"aggs": {
"group_by_state": {
"terms": {
"field": "state.keyword"
}
}
}
}

本文只是对Elasticsearch的基础知识进行了介绍,更多的API接口可以参考官方的reference

参考链接: