参考【阮一峰:全文搜索引擎 Elasticsearch 入门教程】
1、安装初始化环境
a.使用单机开发版
#数据保存到本地
docker run -d --name es --restart=always \
--net mybridge --ip=172.1.111.12 \
-v /home/tools/elasticsearch/single/data/:/usr/share/elasticsearch/data/ \
-e "discovery.type=single-node" \
elasticsearch:7.7.0
b.数据库请求
启动检查
### 系统info
curl -X GET http://172.1.111.12:9200
### 分片索引列表
curl -X GET 'http://172.1.111.12:9200/_cat/indices?v'
### 分片索引列表info
curl -X GET 'http://172.1.111.12:9200/_mapping?pretty=true'
安装中文分词插件,数据库初始化
docker exec -it es bash
./bin/elasticsearch-plugin install 'https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.7.0/elasticsearch-analysis-ik-7.7.0.zip'
exit
docker restart es
### 建立索引目录 accounts
curl -X GET 'http://172.1.111.12:9200/accounts'
### 删除索引
curl -X DELETE 'http://172.1.111.12:9200/accounts'
c.索引类型修改
# 分词设置和修改,可以添加时已经指定、无需修改
# https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-custom-analyzer.html
# https://github.com/medcl/elasticsearch-analysis-ik
curl -X PUT 'http://172.1.111.12:9200/accounts' -d '
{
"settings" : {
"index" : {
"analysis.analyzer.default.type": "ik_max_word"
}
}
}'
# 中文语句分词查询测试:analyzer项可以省略,[ik_max_word|standard]
curl -X PUT 'http://172.1.111.12:9200/accounts/_analyze' -d '
{
"analyzer": "standard",
"text": " ES的默认分词设置是standard,这个在中文分词时就比较尴尬了,会单字拆分"
}' -H 'Content-Type:application/json'
2、增删改查操作
建库建表:建立索引下的对象
这里注意POST、PUT参数 -H 'Content-Type:application/json'
参数。
Content-Type header [application/x-www-form-urlencoded] is not supported
#新建一个名称为accounts的 Index,里面有一个名称为person的 Type。person有三个字段
curl -X PUT 'http://172.1.111.12:9200/accounts' -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"
}
}
}
}
}' -H 'Content-Type:application/json'
a.数据添加
curl -X PUT 'http://172.1.111.12:9200/accounts/person/2' -d '
{
"user": "张三",
"title": "工程师",
"desc": "数据库管理"
}' -H 'Content-Type:application/json'
# 返回
{
"_index": "accounts",
"_type": "person",
"_id": "1",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 0,
"_primary_term": 2
}
# 再添加一条
curl -X PUT 'http://172.1.111.12:9200/accounts/person/2' -d '
{
"user": "张三2",
"title": "工程师",
"desc": "数据库管理"
}' -H 'Content-Type:application/json'
b.数据查看
# 查询总人数,不加-d报错
curl -X POST 'http://172.1.111.12:9200/accounts/person' -d '{}' -H 'Content-Type:application/json'
# 返回
{
"_index": "accounts",
"_type": "person",
"_id": "5oypSXIBsIkVNyXrn1o5",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 3,
"_primary_term": 3
}
# 查询单条记录
curl -X GET 'http://172.1.111.12:9200/accounts/person/1'
# 返回
{"_index":"accounts","_type":"person","_id":"1","_version":1,"_seq_no":0,"_primary_term":2,"found":true,"_source":
{
"user": "张三",
"title": "工程师",
"desc": "数据库管理"
}}
c.数据删除
curl -X DELETE 'http://172.1.111.12:9200/accounts/person/2'
# 返回
{
"_index": "accounts",
"_type": "person",
"_id": "2",
"_version": 2,
"result": "deleted",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
}
}
d.数据更新
curl -X PUT 'http://172.1.111.12:9200/accounts/person/2' -d '
{
"user": "张三2",
"title": "工程师",
"desc": "数据库管理"
}' -H 'Content-Type:application/json'
# 返回
{"_index":"accounts","_type":"person","_id":"2","_version":1,"result":"created","_shards":{"total":2,"successful":1,"failed":0},"_seq_no":6,"_primary_term":3}
curl -X PUT 'http://172.1.111.12:9200/accounts/person/2' -d '
{
"user": "张三233",
"title": "工程师",
"desc": "数据库管理"
}' -H 'Content-Type:application/json'
# 返回
{"_index":"accounts","_type":"person","_id":"2","_version":2,"result":"updated","_shards":{"total":2,"successful":1,"failed":0},"_seq_no":7,"_primary_term":3}
两次返回情况:
_version: 增加
_seq_no: 增加
created -> updated
3、复杂查询
a.查询列表页
curl -X PUT http://172.1.111.12:9200/accounts/person/_search
# 返回
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 5,
"relation": "eq"
},
"max_score": 1.0,
"hits": [{
"_index": "accounts",
"_type": "person",
"_id": "1",
"_score": 1.0,
"_source": {
"user": "张三",
"title": "工程师",
"desc": "数据库管理"
}
}, {
"_index": "accounts",
"_type": "person",
"_id": "sYynSXIBsIkVNyXrfVpX",
"_score": 1.0,
"_source": {
"analyzer": "ik_max_word",
"text": " ES的默认分词设置是standard,这个在中文分词时就比较尴尬了,会单字拆分"
}
}, {
"_index": "accounts",
"_type": "person",
"_id": "5oypSXIBsIkVNyXrn1o5",
"_score": 1.0,
"_source": {}
}, {
"_index": "accounts",
"_type": "person",
"_id": "9IyqSXIBsIkVNyXrLVrA",
"_score": 1.0,
"_source": {}
}, {
"_index": "accounts",
"_type": "person",
"_id": "2",
"_score": 1.0,
"_source": {
"user": "张三233",
"title": "工程师",
"desc": "数据库管理"
}
}]
}
}
由于前面在 ApiPost 的误操作,产生了一些垃圾数据。
total:返回记录数,本例是2条。
max_score:最高的匹配程度,本例是1.0。
hits:返回的记录组成的数组。
b.匹配查询
https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-script-query.html
指定标题搜索[=]
curl -X GET 'http://172.1.111.12:9200/accounts/person/_search' -d '
{
"query": {
"bool": {
"must": [{
"match": {
"title": "师"
}
}],
"filter": []
}
}
}' -H 'Content-Type:application/json'
# 返回
{
"took": 2,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 2,
"relation": "eq"
},
"max_score": 0.10536051,
"hits": [{
"_index": "accounts",
"_type": "person",
"_id": "1",
"_score": 0.10536051,
"_source": {
"user": "张三",
"title": "工程师",
"desc": "数据库管理"
}
}, {
"_index": "accounts",
"_type": "person",
"_id": "2",
"_score": 0.10536051,
"_source": {
"user": "张三233",
"title": "工程师",
"desc": "数据库管理"
}
}]
}
}
增加词量
curl -X GET 'http://172.1.111.12:9200/accounts/person/_search' -d '
{
"query": {
"bool": {
"must": [{
"match": {
"title": "工程师"
}
}],
"filter": []
}
}
}' -H 'Content-Type:application/json'
# 返回
{
"took": 5,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 2,
"relation": "eq"
},
"max_score": 0.31608152,
"hits": [{
"_index": "accounts",
"_type": "person",
"_id": "1",
"_score": 0.31608152,
"_source": {
"user": "张三",
"title": "工程师",
"desc": "数据库管理"
}
}, {
"_index": "accounts",
"_type": "person",
"_id": "2",
"_score": 0.31608152,
"_source": {
"user": "张三233",
"title": "工程师",
"desc": "数据库管理"
}
}]
}
}
会提高 hits.hits._score。
#添加size,限制返回数
{
"query": {"bool":{"must":[{"match":{"title":"工程师"}}],"filter":[]}},
"size": 1
}
c.多条件查询
测试数据
curl -X PUT 'http://172.1.111.12:9200/accounts/person/3' -d '
{
"user": "李明",
"title": "工程师 学习",
"desc": "运维 架构师"
}' -H 'Content-Type:application/json'
curl -X PUT 'http://172.1.111.12:9200/accounts/person/4' -d '
{
"user": "夏天",
"title": "工程师 教育",
"desc": "软件 系统"
}' -H 'Content-Type:application/json'
curl -X PUT 'http://172.1.111.12:9200/accounts/person/5' -d '
{
"user": "呃呃",
"title": "呵呵 123 学习",
"desc": "系统 运维 学习"
}' -H 'Content-Type:application/json'
curl -X PUT 'http://172.1.111.12:9200/accounts/person/6' -d '
{
"user": "明白",
"title": "问问 123 学习",
"desc": "系统 软件 看看"
}' -H 'Content-Type:application/json'
and
搜索,必须使用布尔查询
### or并集查询
curl 'http://172.1.111.12:9200/accounts/person/_search' -d '
{
"query" : { "match" : { "desc" : "软件 系统" }}
}' -H 'Content-Type: application/json'
# 返回
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 3,
"relation": "eq"
},
"max_score": 5.4819746,
"hits": [{
"_index": "accounts",
"_type": "person",
"_id": "4",
"_score": 5.4819746,
"_source": {
"user": "夏天",
"title": "工程师 教育",
"desc": "软件 系统"
}
}, {
"_index": "accounts",
"_type": "person",
"_id": "6",
"_score": 4.7037764,
"_source": {
"user": "明白",
"title": "问问 123 学习",
"desc": "系统 软件 看看"
}
}, {
"_index": "accounts",
"_type": "person",
"_id": "5",
"_score": 1.7504241,
"_source": {
"user": "呃呃",
"title": "呵呵 123 学习",
"desc": "系统 运维 学习"
}
}]
}
}
### 布尔查询交集
curl 'http://172.1.111.12:9200/accounts/person/_search' -d '
{
"query": {
"bool": {
"must": [
{ "match": { "desc": "软件" } },
{ "match": { "desc": "系统" } }
]
}
}
}' -H 'Content-Type: application/json'
# 返回
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 2,
"relation": "eq"
},
"max_score": 5.4819746,
"hits": [{
"_index": "accounts",
"_type": "person",
"_id": "4",
"_score": 5.4819746,
"_source": {
"user": "夏天",
"title": "工程师 教育",
"desc": "软件 系统"
}
}, {
"_index": "accounts",
"_type": "person",
"_id": "6",
"_score": 4.7037764,
"_source": {
"user": "明白",
"title": "问问 123 学习",
"desc": "系统 软件 看看"
}
}]
}
}
布尔查询排除
query.bool: {must: [],must_not: []}
d.分页排序
排序输出 sort
# sort by asc/desc
{
"query": { "match_all": {"desc": "软件"} },
"sort": [
{ "_id": "asc" }
]
}
返回
{
"took": 22,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 3,
"relation": "eq"
},
"max_score": null,
"hits": [{
"_index": "accounts",
"_type": "person",
"_id": "4",
"_score": null,
"_source": {
"user": "夏天",
"title": "工程师 教育",
"desc": "软件 系统"
},
"sort": ["4"]
}, {
"_index": "accounts",
"_type": "person",
"_id": "5",
"_score": null,
"_source": {
"user": "呃呃",
"title": "呵呵 123 学习",
"desc": "系统 运维 学习"
},
"sort": ["5"]
}, {
"_index": "accounts",
"_type": "person",
"_id": "6",
"_score": null,
"_source": {
"user": "明白",
"title": "问问 123 学习",
"desc": "系统 软件 看看"
},
"sort": ["6"]
}]
}
}
分页输出 from-size
{
"query": {
"match_all": {"desc": "软件"}
},
"sort": [{
"account_number": "asc"
}],
"from": 10,
"size": 10
}
f.有限范围查询
# filter.range.[范围字段balance]: {"gte": 2000,"lte": 30000}
{
"query": {
"bool": {
"must": { "match_all": {} },
"filter": {
"range": {
"balance": {
"gte": 20000,
"lte": 30000
}
}
}
}
}
}
总结
a.查询
query.match_all
简单查询
query.match: {字段1:值1, 字段2:值2}
交集查询
query.bool: {must: [match{}],must_not: []}
排序分页
sort: [{ "_id": "asc" }]
from: 10,
size: 10限定范围
filter.range.[范围字段balance]: {"gte": 2000,"lte": 30000}
b.官方文档
查询文档https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl.html
c.小结
使用约定的JSON数组查询,省去了DDL语句解析的时间;典型的使用RESTFUL-API风格请求响应,可以简化后端操作,基本功能甚至不需要后端开发的参与。