初步检索
_cat
GET _cat/nodes:查看所有节点
GET _cat/health:查看es健康状况
GET _cat/master 查看主节点
GET _cat/indices:查看索引
索引一个文档
PUT http://10.1.100.10:9200/customer/external/1
{
"name": "John Doe"
}
结果:
{
"_index": "customer",
"_type": "external",
"_id": "1",
"_version": 2,
"result": "updated",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 1,
"_primary_term": 1
}
带ID保存,保存多次的话为更新。
POST保存,不带ID操作
http://10.1.100.10:9200/customer/external/
{
"name": "John Doe"
}
结果:
{
"_index": "customer",
"_type": "external",
"_id": "ixGvLHMBhCErS6Ql1rmD",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 2,
"_primary_term": 1
}
ES自动生成一个ID。
POST和PUT不带ID都是新增,带ID就是更新,都是保存更新二合一,PUT与POST区别就是需要带ID。
查询文档
http://10.1.100.10:9200/customer/external/1
{
"_index": "customer", //在哪个索引
"_type": "external", //在哪个类型
"_id": "1", //记录ID
"_version": 2, //版本号
"_seq_no": 1, //并发控制字段,每次更新都会加1,用来做乐观锁
"_primary_term": 1, //同上。主分片重新分配,如重启,会有变化
"found": true,
"_source": { //真正内容
"name": "John Doe"
}
}
乐观锁修改
PUT http://10.1.100.10:9200/customer/external/1?if_seq_no=1&if_primary_term=1
{
"name": "1"
}
第一次执行结果:
{
"_index": "customer",
"_type": "external",
"_id": "1",
"_version": 3,
"result": "updated",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 3,
"_primary_term": 1
}
第二次执行结果:
{
"error": {
"root_cause": [
{
"type": "version_conflict_engine_exception",
"reason": "[1]: version conflict, required seqNo [1], primary term [1]. current document has seqNo [3] and primary term [1]",
"index_uuid": "vl1cfQwKRKSj9c4pe5Wglg",
"shard": "0",
"index": "customer"
}
],
"type": "version_conflict_engine_exception",
"reason": "[1]: version conflict, required seqNo [1], primary term [1]. current document has seqNo [3] and primary term [1]",
"index_uuid": "vl1cfQwKRKSj9c4pe5Wglg",
"shard": "0",
"index": "customer"
},
"status": 409
}
更新文档
http://10.1.100.10:9200/customer/external/1/_update
{
"doc": {
"name": "6"
}
}
{
"_index": "customer",
"_type": "external",
"_id": "1",
"_version": 5,
"result": "updated",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 5,
"_primary_term": 1
}
第二次执行
{
"_index": "customer",
"_type": "external",
"_id": "1",
"_version": 4,
"result": "noop",
"_shards": {
"total": 0,
"successful": 0,
"failed": 0
},
"_seq_no": 4,
"_primary_term": 1
}
会对比原来数据看是否需要更新,如果不需要更新,则result为noop,版本号等不变,具体对比看上面结果。
POST http://10.1.100.10:9200/customer/external/1
{
"name": "1"
}
第一次执行
{
"_index": "customer",
"_type": "external",
"_id": "1",
"_version": 8,
"result": "updated",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 8,
"_primary_term": 1
}
第二次执行
{
"_index": "customer",
"_type": "external",
"_id": "1",
"_version": 9,
"result": "updated",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 9,
"_primary_term": 1
}
两次执行结果_version和_seq_no会增加。
PUT http://10.1.100.10:9200/customer/external/1
{
"name": "1"
}
第一次执行
{
"_index": "customer",
"_type": "external",
"_id": "1",
"_version": 10,
"result": "updated",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 10,
"_primary_term": 1
}
第二次执行
{
"_index": "customer",
"_type": "external",
"_id": "1",
"_version": 11,
"result": "updated",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 11,
"_primary_term": 1
}
两次执行结果_version和_seq_no会增加。
得出结论:只有POST携带doc请求的请求才会去检查版本!
增加字段
PUT http://10.1.100.10:9200/customer/external/1
{
"name": "1",
"age": 123
}
POST http://10.1.100.10:9200/customer/external/1
{
"name": "1",
"age": 123,
"desc":"sssss"
}
删除
DELETE http://10.1.100.10:9200/customer/external/1
返回结果
{
"_index": "customer",
"_type": "external",
"_id": "1",
"_version": 16,
"result": "deleted",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 16,
"_primary_term": 1
}
再次查询
GET http://10.1.100.10:9200/customer/external/1
返回结果
{
"_index": "customer",
"_type": "external",
"_id": "1",
"found": false
}
删除索引
DELETE http://10.1.100.10:9200/customer
返回结果
{
"acknowledged": true
}
批量增加
POST /customer/external/_bulk
{"index":{"_id":"1"}}
{"name": "Mike"}
{"index":{"_id":"2"}}
{"name": "Mike"}
结果
#! Deprecation: [types removal] Specifying types in bulk requests is deprecated.
{
"took" : 672,
"errors" : false,
"items" : [
{
"index" : {
"_index" : "customer",
"_type" : "external",
"_id" : "1",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 0,
"_primary_term" : 1,
"status" : 201
}
},
{
"index" : {
"_index" : "customer",
"_type" : "external",
"_id" : "2",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 1,
"_primary_term" : 1,
"status" : 201
}
}
]
}
批量对所有索引进行操作
POST /_bulk
{"delete":{"_index":"website","_type":"blog","_id":"123"}}
{"create":{"_index":"website","_type":"blog","_id":"123"}}
{"title":"My first blog post"}
{"index":{"_index":"website","_type":"blog"}}
{"title":"My second blog post"}
{"update": {"_index":"website", "_type": "blog", "_id": "123"}}
{"doc":{"title":"My update blog post"}}
结果
#! Deprecation: [types removal] Specifying types in bulk requests is deprecated.
{
"took" : 791,
"errors" : false,
"items" : [
{
"delete" : {
"_index" : "website",
"_type" : "blog",
"_id" : "123",
"_version" : 1,
"result" : "not_found",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 0,
"_primary_term" : 1,
"status" : 404
}
},
{
"create" : {
"_index" : "website",
"_type" : "blog",
"_id" : "123",
"_version" : 2,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 1,
"_primary_term" : 1,
"status" : 201
}
},
{
"index" : {
"_index" : "website",
"_type" : "blog",
"_id" : "0xFxLXMBhCErS6QlDMua",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 2,
"_primary_term" : 1,
"status" : 201
}
},
{
"update" : {
"_index" : "website",
"_type" : "blog",
"_id" : "123",
"_version" : 3,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 3,
"_primary_term" : 1,
"status" : 200
}
}
]
}
可以看出来进行了四次操作,具体分析看上面结果。
样例数据
https://github.com/elastic/elasticsearch/blob/master/docs/src/test/resources/accounts.json
通过命令将样例数据导入到es
POST /bank/_bulk
进阶检索
REST URI:
GET /bank/_search?q=*&sort=account_number:asc
REST BOdy:
GET bank/_search
{
"query": {
"match_all": {}
},
"sort": [
{
"account_number": "asc"
}
]
}
GET bank/_search
{
"query": {
"match_all": {}
},
"sort": [
{
"account_number": "asc"
}
]
}
GET bank/_search
{
"query": {
"match": {
"account_number": "3"
}
}
}
#全文检索,会对检索条件进行分词
GET bank/_search
{
"query": {
"match": {
"address": "Wilson Street"
}
}
}
#短语匹配
GET bank/_search
{
"query": {
"match_phrase": {
"address": "Wilson Street"
}
}
}
#多字段匹配,会进行分词操作
GET bank/_search
{
"query": {
"multi_match": {
"query": "mill Road",
"fields": ["address", "city"]
}
}
}
#复杂查询
GET bank/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"gender": "m"
}
}
], "must_not": [
{"match": {
"age": "39"
}}
],
"should": [
{"match": {
"lastname": "Duke"
}}
]
}
}
}
GET bank/_search
{
"query": {
"bool": {
"must": [
{"range": {
"age": {
"gte": 10,
"lte": 20
}
}}
]
}
}
}
#filter不会计算相关性得分
GET bank/_search
{
"query": {
"bool": {
"filter": [
{
"range": {
"age": {
"gte": 10,
"lte": 20
}
}
}
]
}
}
}
#精确匹配term
GET bank/_search
{
"query": {
"term": {
"age": {
"value": "20"
}
}
}
}
#精准匹配keyword
GET bank/_search
{
"query": {
"match": {
"address.keyword": "741 McDonald"
}
}
}
GET bank/_search
{
"query": {
"match": {
"address": "741 McDonald"
}
}
}
聚合
##搜索address中包含mill的所有人的年龄分布和平均年龄
GET bank/_search
{
"query": {
"match": {
"address": "mill"
}
},
"aggs": {
"ageAgg": {
"terms": {
"field": "age",
"size": 10
}
},
"ageAvg":{
"avg": {
"field": "age"
}
},
"balanceAge":{
"avg": {
"field": "age"
}
}
},
"size": 0
}
##按照年龄聚合,并且请求这些年龄段的这些人的平均薪资
GET bank/_search
{
"query": {
"match_all": {}
},
"aggs": {
"ageAgg": {
"terms": {
"field": "age",
"size": 100
},
"aggs": {
"ageAvg": {
"avg": {
"field": "balance"
}
}
}
}
}
}
#查询所有年龄分布,并且这些年龄段中F和M的平均薪资及这个年龄段的平均薪资
GET bank/_search
{
"query": {
"match_all": {}
},
"aggs": {
"ageAvg": {
"terms": {
"field": "age",
"size": 100
},
"aggs": {
"genderaAgg": {
"terms": {
"field": "gender.keyword",
"size": 100
},
"aggs": {
"banlanceAvg": {
"avg": {
"field": "balance"
}
}
}
},
"ageBalanceAvg" :{
"avg": {
"field": "balance"
}
}
}
}
},
"size": 0
}
Mapping
#查看映射
GET myindex/_mapping
#创建索引
PUT /myindex
{
"mappings": {
"properties": {
"age" :{"type": "integer"},
"email":{"type": "keyword"},
"name":{"type": "text"}
}
}
}
#添加新字段
PUT myindex/_mapping
{
"properties": {
"employ_id":{"type":"keyword"}
}
}
#修改映射,需要先将数据迁移后,再将数据导入过去
POST _reindex
{
"source": {"index": "bank"},
"dest": {"index": "new_bank"}
}
#有type导数据
POST _reindex
{
"source": {"index": "bank","type": "account"},
"dest": {"index": "new_bank"}
}
##分词器安装
下载 wget https://github.com/medcl/elasticsearch-analysis-ik/releases
并解压到plugins/ik目录
bin/elasticsearch-plugin list
重启即可
测试中文分词器
#中文分词器
GET /_analyze
{
"analyzer": "ik_smart",
"text": "我是中国人"
}
GET /_analyze
{
"analyzer": "ik_max_word",
"text": "我是中国人"
}