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 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" } }
通过上述简单的指令可以看到,我们可以使用比较固定的模式<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也提供了_bulk
API来进行批量操作,如下的例子中将会首先更新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 }
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"] }
匹配某个字段,注意match
和match_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 。
参考链接: