elasticsearch操作
基本概念
Cluster 集群
群集是一个或多个节点(服务器)的集合, 这些节点共同保存整个数据,并在所有节点上提供联合索引和搜索功能。一个集群由一个唯一集群ID确定,并指定一个集群名(默认为“elasticsearch”)。该集群名非常重要,因为节点可以通过这个集群名加入群集,一个节点只能是群集的一部分。
Node节点
节点是单个服务器实例,它是群集的一部分,可以存储数据,并参与群集的索引和搜索功能。就像一个集群,节点的名称默认为一个随机的通用唯一标识符(UUID),确定在启动时分配给该节点。如果不希望默认,可以定义任何节点名。这个名字对管理很重要,目的是要确定你的网络服务器对应于你的ElasticSearch群集节点。
Index索引
索引是具有相似特性的文档集合。例如,可以为客户数据提供索引,为产品目录建立另一个索引,以及为订单数据建立另一个索引。索引由名称(必须全部为小写)标识,该名称用于在对其中的文档执行索引、搜索、更新和删除操作时引用索引。在单个群集中,您可以定义尽可能多的索引。
Type类型
在索引中,可以定义一个或多个类型。类型是索引的逻辑类别/分区,其语义完全取决于您。一般来说,类型定义为具有公共字段集的文档。例如,假设你运行一个博客平台,并将所有数据存储在一个索引中。在这个索引中,您可以为用户数据定义一种类型,为博客数据定义另一种类型,以及为注释数据定义另一类型。
Document文档
文档是可以被索引的信息的基本单位。例如,您可以为单个客户提供一个文档,单个产品提供另一个文档,以及单个订单提供另一个文档。本文件的表示形式为JSON(JavaScript Object Notation)格式,这是一种非常普遍的互联网数据交换格式。
在索引/类型中,您可以存储尽可能多的文档。请注意,尽管文档物理驻留在索引中,文档实际上必须索引或分配到索引中的类型。
Shards & Replicas分片与副本
索引可以存储大量的数据,这些数据可能超过单个节点的硬件限制。例如,十亿个文件占用磁盘空间1TB的单指标可能不适合对单个节点的磁盘或可能太慢服务仅从单个节点的搜索请求。
为了解决这一问题,Elasticsearch提供细分你的指标分成多个块称为分片的能力。当你创建一个索引,你可以简单地定义你想要的分片数量。每个分片本身是一个全功能的、独立的“指数”,可以托管在集群中的任何节点。
Shards分片的重要性主要体现在以下两个特征:
分片允许您水平拆分或缩放内容的大小
分片允许你分配和并行操作的碎片(可能在多个节点上)从而提高性能/吞吐量
这个机制中的碎片是分布式的以及其文件汇总到搜索请求是完全由ElasticSearch管理,对用户来说是透明的。
在同一个集群网络或云环境上,故障是任何时候都会出现的,拥有一个故障转移机制以防分片和结点因为某些原因离线或消失是非常有用的,并且被强烈推荐。为此,Elasticsearch允许你创建一个或多个拷贝,你的索引分片进入所谓的副本或称作复制品的分片,简称Replicas。
Replicas的重要性主要体现在以下两个特征:
副本为分片或节点失败提供了高可用性。为此,需要注意的是,一个副本的分片不会分配在同一个节点作为原始的或主分片,副本是从主分片那里复制过来的。
副本允许用户扩展你的搜索量或吞吐量,因为搜索可以在所有副本上并行执行。
映射(Mapping)
映射用于映射文档的每个field及其对应的数据类型,例如字符串、整数、浮点数、双精度数、日期等等。在索引创建过程中,elasticsearch会自动创建一个针对fields的映射,并且根据特定的需求类型,可以很容易地查询或修改这些映射。
text类型会分开解析,keyword类型不会解析
使用ES
curl -X<VERB> '<PROTOCOL>://<HOST>:<PORT>/<PATH>?<QUERY\_STRING>' -d '<BODY>'
VERB
适当的 HTTP 方法 或 谓词 : GET、
POST、
PUT、
HEAD 或者 DELETE
。
PROTOCOL
http 或者 http(如果你在 Elasticsearch 前面有一个
http 代理)
HOST
Elasticsearch 集群中任意节点的主机名,或者用 localhost 代表本地机器上的节点。
PORT
运行 Elasticsearch HTTP 服务的端口号,默认是 9200 。
PATH
API 的终端路径(例如 _count 将返回集群中文档数量)。Path 可能包含多个组件,例如:_cluster/stats 和 _nodes/stats/jvm 。
QUERY_STRING
任意可选的查询字符串参数 (例如 ?pretty 将格式化地输出 JSON 返回值,使其更容易阅读)
BODY
一个 JSON 格式的请求体 (如果请求需要的话)
插入数据
[root@localhost ~]# curl -X PUT "192.168.57.3:9200/jcwit/employee/1" -H 'Content-Type:application/json' -d '{"first_name":"lei","last_name":"li","age":18,"desc":"I like girl","fav":["music","sports"]}'
{"_index":"jcwit","_type":"employee","_id":"1","_version":1,"result":"created","_shards":{"total":2,"successful":2,"failed":0},"_seq_no":0,"_primary_term":1}
注意,路径 /jcwit/employee/1 包含了三部分的信息:
jcwit
索引名称index
employee
类型名称type
1
特定雇员的ID
获取数据
[root@localhost ~]# curl -X GET "192.168.57.3:9200/jcwit/employee/1?pretty"
{
"_index" : "jcwit",
"_type" : "employee",
"_id" : "1",
"_version" : 2,
"_seq_no" : 1,
"_primary_term" : 1,
"found" : true,
"_source" : {
"first_name" : "lei",
"last_name" : "li",
"age" : 18,
"desc" : "I like girl",
"fav" : [
"music",
"sports"
]
}
}
根据条件搜索
curl -X GET "192.168.57.4:9200/jcwit/employee/_search?q=first_name:lei"
#新版7.0取消多type直接用_doc即可 创建可以用_doc或者_create
PUT zhihu/jobs/1
{
"title":"Python开发",
"monery":30000,
"city":"北京",
"company":{
"name":"百度",
"addr":"中关村"
}
}
PUT zhihu/_doc/3
{
"title":"PHP开发",
"monery":30000,
"city":"北京",
"company":{
"name":"百度",
"addr":"中关村"
}
}
#match查询,模糊匹配相当于like
#from从第一个索引开始,size一页显示几个
GET zhihu/_search
{
"query": {
"match": {
"title": "开发"
}
},
"from": 0,
"size": 2
}
#term查询 使用小写字母查询 后台会把大写转换为小写 如果使用PHP查询会找不到结果
GET zhihu/_search
{
"query": {
"term": {
"title": "php"
}
}
}
GET zhihu/_search
{
"query": {
"terms": {
"title": [
"php",
"python"
]
}
}
}
#查询所有
GET zhihu/_search
{
"query": {
"match_all": {}
}
}
#完全匹配字段中的每一项才会被搜索到
GET zhihu/_search
{
"query": {
"match_phrase": {
"title": "PHP开发"
}
}
}
#多个字段中都能搜索到Python返回结果
GET zhihu/_search
{
"query": {
"multi_match": {
"query": "Python",
"fields": ["title","name"]
}
}
}
#指定返回字段,需要在mapping中设置stored为true,默认为false
GET zhihu/_search
{
"stored_fields": ["title","city"],
"query": {
"match": {
"title": "开发"
}
}
}
#排序asc或desc
GET zhihu/_search
{
"query": {
"match_all": {}
},
"sort": [
{
"monery": {
"order": "desc"
}
}
]
}
#查询范围
GET zhihu/_search
{
"query": {
"range": {
"monery": {
"gte": 1000,
"lte": 40000
}
}
}
}
#正则模糊匹配,7.0我没搜索到 ,
GET zhihu/_search
{
"query": {
"wildcard": {
"title": {
"value": "Pyth*n"
}
}
}
}
复合搜索
curl -XGET "http://192.168.57.3:9200/jcwit/_search" -H 'Content-Type: application/json' -d'
{
"query" : {
"bool": {
"must": {
"match" : {
"last_name" : "li"
}
},
"filter": {
"range" : {
"age" : { "lt" : 20 }
}
}
}
}
}'
filter dsl:
term filter: 精确匹配包含指定term的文档{“term”:{“last_name” : “smith” }}
terms filter: 用于实现多个值精确匹配,关系为或 {“term”:{“last_name” :{ “smith”,”lilei”} }}
range filter 用于在指定范围内查找数值或时间。gt lt gte lte
exists ans missing filter 判断存在与否
布尔过滤器
一个 bool 过滤器由三部分组成:
{
"bool" : {
"filter": [],
"must" : [],
"should" : [],
"must_not" : [],
}
}
must 内部语句必须必须匹配 相当于and
must_not 内部语句必须不匹配
should 至少有一个语句匹配 相当于or
filter 过滤
query dsl:
match_all 用于匹配所有文档,没有指定默认为match_all
match 在几乎任何域上执行full-text或者exact_value 查询
如果执行full-text 首先对查询语句分析{“match”:{employee:”Switch”}}
如果执行exact-text 搜索精确值,此时 建议使用过滤而非查询 {“match”:{name:”Switch”}}
multi-match 用于在多于上执行相同的查询
{
"multi_match":
"query":""
"field":""
}
一些复杂查询案例
POST zhilian/_bulk
{"index":{"_id":1}}
{"salary":10000,"title":"Python"}
{"index":{"_id":2}}
{"salary":20000,"title":"PHP"}
{"index":{"_id":3}}
{"salary":30000,"title":"JAVA"}
{"index":{"_id":4}}
{"salary":40000,"title":"C++"}
#薪资为20000的数据
GET zhilian/_search
{
"query": {
"bool": {
"must": [
{
"match_all": {}
}
],
"filter": {
"term": {
"salary": 20000
}
}
}
}
}
#查询薪资为10000或者20000的
GET zhilian/_search
{
"query": {
"bool": {
"must": [
{
"match_all": {}
}
],
"filter": {
"terms": {
"salary": [
10000,
20000
]
}
}
}
}
}
#查询薪资为10000到20000的
GET zhilian/_search
{
"query": {
"bool": {
"must": [
{
"match_all": {}
}
],
"filter": {
"range": {
"salary": {
"gte": 10000,
"lte": 20000
}
}
}
}
}
}
#term 查询 分析器会解析为小写,所以这里我们搜索条件为python而不是Python
GET zhilian/_search
{
"query": {
"bool": {
"must": [
{ "match_all": {}}
],
"filter": {
"term": {
"title": "python"
}
}
}
}
}
#查看分析器解析的结果ik_smart和ik_max_word
#安装ik插件
/usr/share/elasticsearch/bin/elasticsearch-plugin install [http://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.1.0/elasticsearch-analysis-ik-7.1.0.zip](http://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.1.0/elasticsearch-analysis-ik-7.1.0.zip)
GET _analyze
{
"analyzer": "ik_max_word",
"text": "PHP学习"
}
#查询薪资一定不等于30000的,等于20000的或者title为python的
GET zhilian/_search
{
"query": {
"bool": {
"should": [
{"term": {
"salary": 20000
}},
{"term": {
"title": "python"
}
}
],
"must_not": [
{"term": {
"salary": 30000
}}
]
}
}
}
#查询嵌套bool套bool 查询title等于python的或者 title等于php薪资必须等于20000的
GET zhilian/_search
{
"query": {
"bool": {
"should": [
{"term":{"title":"python"}},
{"bool": {
"must": [
{"term":{"title":"php"}},
{"term":{"salary":20000}}
]
}}
]
}
}
}
#过滤空和非空
#查询 存在字段title的,must_not查询不存在字段的或者为null的
GET zhilian/_search
{
"query": {
"bool": {
"filter": {
"exists": {
"field": "title"
}
}
}
}
}
删除操作
根据ID删除
curl -X DELETE "192.168.57.4:9200/jcwit/employee/1"
根据条件删除
curl POST /jcwit/_delete_by_query
{
"query": {
"match": {
"age": 18
}
}
}
更新操作
根据ID局部更新
curl -X POST "http://192.168.57.3:9200/jcwit/_update/2" -H 'Content-Type: application/json' -d'
{
"doc": {
"age":20
}
}'
获取多个mget
不指定索引获取
curl -XGET "http://192.168.57.3:9200/_mget" -H 'Content-Type: application/json' -d'
{
"docs" : [
{
"_index" : "jcwit",
"_id" : "1"
},
{
"_index" : "jcwit",
"_id" : "2"
}
]
}'
指定索引获取
curl -XGET "http://192.168.57.3:9200/jcwit/_mget" -H 'Content-Type: application/json' -d'
{
"docs" : [
{
"_id" : "1"
},
{
"_id" : "2"
}
]
}'
也可以这么写
curl -XGET "http://192.168.57.3:9200/jcwit/_mget" -H 'Content-Type: application/json' -d'
{
"ids" : ["1", "2"]
}'