1. 安装
以Windows版为例。
ElasticSearch官网下载:
https://www.elastic.co/cn/elasticsearch/
解压后无需安装,在bin文件夹下找到elasticsearch.bat文件,双击运行即可。会弹出cmd窗口
ES使用RESTFUL API操作,可以安装Postman以方便使用:
https://www.postman.com/
2. 基本操作
2.1 索引库操作
2.1.1 创建索引库
ES本地默认地址是:
http://127.0.0.1:9200/
首先创建一个名为shopping的索引库(index)
[PUT] http://127.0.0.1:9200/shopping
返回"acknowledged": true说明创建成功。注意不支持使用POST,因为是幂等操作(输出是唯一的)。
2.1.2 查看索引库
要查看只须方法改为GET即可
[GET] http://127.0.0.1:9200/shopping
2.1.3 删除索引库
要删除只须把方法改为DELETE即可
[DELETE] http://127.0.0.1:9200/shopping
返回"acknowledged": true说明删除成功。
2.2 文档操作
先把文档内容以JSON格式写入Body。注意选择raw和JSON
2.2.1 不指定ID创建文档
不指定ID创建文档,只能用POST方法
[POST] http://127.0.0.1:9200/shopping/_doc/
这样每次执行都会创建一个新的文档,随机给定一个ID。所以是非幂等操作,不能用PUT方法。执行一次:
再执行一次:
可以看到两次ID不一样。全量查询所有文档:
[GET] http://127.0.0.1:9200/shopping/_search
返回如下
{
"took": 1331,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 2,
"relation": "eq"
},
"max_score": 1.0,
"hits": [
{
"_index": "shopping",
"_type": "_doc",
"_id": "Ta_XpnwB9VExessDRbAp",
"_score": 1.0,
"_source": {
"title": "小米手机",
"category": "小米",
"images": "http://www.gulixueyuan.com/xm.jpg",
"price": 4999.00
}
},
{
"_index": "shopping",
"_type": "_doc",
"_id": "Tq_bpnwB9VExessDmbD_",
"_score": 1.0,
"_source": {
"title": "小米手机",
"category": "小米",
"images": "http://www.gulixueyuan.com/xm.jpg",
"price": 4999.00
}
}
]
}
}
能看到上述创建的两个文档。
2.2.2 指定ID创建文档
在上面命令的基础上加上ID名即可
[POST] http://127.0.0.1:9200/shopping/_doc/1001
使用PUT也是一样的效果
[PUT] http://127.0.0.1:9200/shopping/_doc/1001
若再次发送相同指令,则是更新此文档,且版本号累加
另外,也可以用_create来创建新文档,POST或PUT都可
[POST] http://127.0.0.1:9200/shopping/_create/1002
或
[PUT] http://127.0.0.1:9200/shopping/_create/1002
注意,_create必须指定ID(否则报错),且不能用于更新文档(对相同ID再次执行会报错)
2.2.3 全量更新文档
在2.2.2已提到,对已存在的文档再次执行_doc即为全量更新文档
[POST] http://127.0.0.1:9200/shopping/_doc/1001
或
[PUT] http://127.0.0.1:9200/shopping/_doc/1001
2.2.4 局部更新文档
比如修改1001的title,那么先要在Body输入如下JSON内容
{
"doc":{
"title":"华为手机"
}
}
因为局部更新应返回不同结果,所以是非幂等的,所以只能用POST不能用PUT
[POST] http://127.0.0.1:9200/shopping/_update/1001
更新有自检能力,若重复执行相同JSON则result是noop,表示并没有更新
2.2.5 删除文档
用DELETE和_doc即可删除指定ID的文档
[DELETE] http://127.0.0.1:9200/shopping/_doc/1001
2.3 查询操作
2.3.1 全量查询
前面有演示过,全量查询某索引库使用_search
[GET] http://127.0.0.1:9200/shopping/_search
若在Body中输入如下内容效果一样
{
"query":{
"match_all":{}
}
}
如果查询结果很多,则可以指定返回从第几个开始(from)往后几个(size)。如返回从第2个开始往后3个文档,则输入
{
"query":{
"match_all":{}
},
"from":2,
"size":3
}
注意from是从0开始的!
也可以只显示文档的部分字段,比如只显示title和category
{
"query":{
"match_all":{}
},
"_source":["title","category"]
}
还可以排序,如按price降序排列
{
"query":{
"match_all":{}
},
"sort":{
"price":{
"order":"desc"
}
}
}
2.3.2 条件查询
如查询category为“小米”的文档
[GET] http://127.0.0.1:9200/shopping/_search?q=category:小米
上面是通过请求路径传递参数(?q=category:小米),也可以通过请求体传递参数。在Body中输入以下JSON内容
{
"query":{
"match":{
"category":"小米"
}
}
}
然后发送_search请求
[GET] http://127.0.0.1:9200/shopping/_search
效果与使用请求路径传递参数相同
如果需要多条件查询,则要使用"bool"关键字和关系关键字(如“且”="must",“或”="should)
例如,查询category为小米且price为4999.00
{
"query":{
"bool":{
"must":[
{
"match":{
"category":"小米"
}
},
{
"match":{
"price":4999.00
}
}
]
}
}
}
注意must后的中括号,里面包裹了两个JSON体。然后发送_search请求
[GET] http://127.0.0.1:9200/shopping/_search
又如,想查询category为小米或华为
{
"query":{
"bool":{
"should":[
{
"match":{
"category":"小米"
}
},
{
"match":{
"category":"华为"
}
}
]
}
}
}
然后发送
[GET] http://127.0.0.1:9200/shopping/_search
如果要查询范围,比如price大于4000
{
"query":{
"bool":{
"filter":{
"range":{
"price":{
"gt":4000 //greater than
}
}
}
}
}
}
然后发送
[GET] http://127.0.0.1:9200/shopping/_search
2.3.3 完全匹配
match是全文检索,就是说被查询的关键字会被分词后查询。比如“小米”会被分为“小”和“米”,只要包含这两个字任意一个的文档都会被返回。如果不想这样就要使用match_phrase来做完全匹配查询
{
"query":{
"match_phrase":{
"category":"小米"
}
}
}
然后发送
[GET] http://127.0.0.1:9200/shopping/_search
这样则必须包含“小米”(顺序也不能变,不能是“米小”)的文件才会被返回
也可以增加highlight字段,在查询结果中高亮显示关键字
{
"query":{
"match":{
"category":"小米"
}
},
"highlight":{
"fields":{
"category":{}
}
}
}
然后发送
[GET] http://127.0.0.1:9200/shopping/_search
2.3.4 聚合查询
可以按字段来做统计。比如统计不同价格各有多少
{
"aggs":{ //聚合操作
"price_group":{ //名称(自定义)
"terms":{ //分组
"field":"price" //分组字段
}
}
},
"size":0 //不显示原始数据
}
然后发送
[GET] http://127.0.0.1:9200/shopping/_search
说明5999有2个,999有1个,4999有1个
也可以求平均值
{
"aggs":{ //聚合操作
"price_avg":{ //名称(自定义)
"avg":{ //平均值
"field":"price" //被处理字段
}
}
},
"size":0 //不显示原始数据
}
同样发送
[GET] http://127.0.0.1:9200/shopping/_search
平均值是4499
2.4 映射关系
对于某个字段,是否可以分词查询,甚至是否可以被查询,都是可以设置的。比如新建一个名为user的索引
http://127.0.0.1:9200/user
它包含三种字段:name,sex,tel。我们在body中设置它们的属性如下
{
"properties":{
"name":{
"type":"text", //text可被分词查询
"index":true //true表示可以被查询
},
"sex":{
"type":"keyword", //keyword不能被分词查询,必须完全匹配才会返回
"index":true //true表示可以被查询
},
"tel":{
"type":"keyword", //keyword不能被分词查询,必须完全匹配才会返回
"index":false //false表示不能被查询
}
}
}
发送指令
[PUT] http://127.0.0.1:9200/user/_mapping
即设置字段属性完成。
然后我们可以新建一个文档做测试
{
"name":"高达",
"sex":"男人",
"tel":1111
}
发送指令
[POST] http://127.0.0.1:9200/user/_doc/1004
创建完成。然后我们尝试对name索引
{
"query":{
"match":{
"name":"高"
}
}
}
发送指令
http://127.0.0.1:9200/user/_search
能查询到,因为name的类型是text,可以被分词查询。
再尝试查询sex
{
"query":{
"match":{
"sex":"男"
}
}
}
发送指令
http://127.0.0.1:9200/user/_search
没有查询到,因为sex的类型是keyword,不能分词,必须完整匹配“男人”才能被查询到。
最后尝试查询tel
{
"query":{
"match":{
"tel":1111
}
}
}
发送指令
http://127.0.0.1:9200/user/_search
查询失败,“it is not indexed”,因为设置mapping时候将tel的index属性设为了false
Reference:
【尚硅谷】ElasticSearch教程入门到精通(基于ELK技术栈elasticsearch 7.8.x版本)_哔哩哔哩_bilibili