文章目录
一、安装Elasticsearch和kibana
Elasticsearch单机版+ik分词:
https://blog.csdn.net/qq_34497272/article/details/107663203
kibana(Elasticsearch可视化):
https://blog.csdn.net/qq_34497272/article/details/107665031
二、基本概念
- index:索引
动词:相当于mysql的插入
名词:相当于mysql的库 - Type:类型(7.0之后去除了类型)
在index(索引)中可以添加一个或多个类型,相当于mysql的表 - document:文档
保存在索引下某个类型下的一条数据,文档格式是json格式的,相当于mysql表中的一行数据 - 倒排索引
三、简单操作
- 测试链接:get请求 http://192.168.0.130:9200
- 查看结点信息:get请求 http://192.168.0.130:9200/_cat/nodes
- 健康状况:get请求 http://192.168.0.130:9200/_cat/health
- 查看主结点:get请求:http://192.168.0.130:9200/_cat/master
- 查看所有索引:get请求:http://192.168.0.130:9200/_cat/indices
- put带ID操作(添加/修改)
第一次为添加,后续操作均为修改,每次操作_version(版本号)、_seq_no(序列号)均会变化
customer:索引,external:类型,1:ID - post请求
有ID:第一次为添加,后续为修改
无ID:每次均为添加,会自动生成ID
每次操作_version(版本号)、_seq_no(序列号)均会变化
- 查询文档(查询数据) :get请求:http://192.168.0.130:9200/customer/external/1
{
"_index": "customer", # 在那个索引下
"_type": "external", # 在那个类型下
"_id": "1", # ID
"_version": 2, # 版本号
"_seq_no": 1, # 并发控制字段,每次更新均会加一,用来做乐观锁
"_primary_term": 1, # 同上,主分片重新分配,如重启,则会变化
"found": true,
"_source": { # 实际内容
"name": "测试1"
}
}
- 乐观锁修改
加上if_seq_no=3&if_primary_term=1,若一致则修改,若不一致,则会返回错误信息(409)
- post带_update保存
会对比原数据,若一致则不做任何操作,_version(版本号)、_seq_no(序列号)均不变。参数需要使用doc包裹,例:
{
"doc":{
"name":"测试"
}
}
10. 删除一条数据:delete请求:http://192.168.0.130:9200/customer/external/1
11. 删除customer整个索引:http://192.168.0.130:9200/customer/
注:Elasticsearch无删除类型的操作,可以删除类型内所有的document。
----------以上测试均使用postman,后续测试开始使用kibana--------------
12. 批量操作(简单)
语法格式:
// action操作类型:index表示索引,插入,也可以为delete,update等
// metadata原数据:可以指定索引,类型,ID等信息
{action:{metadata}}
{请求体内容}
{action:{metadata}}
{请求体内容}
POST /customer/external/_bulk
{"index":{"_id":"1"}}
{"name":"测试数据"}
{"index":{"_id":"2"}}
{"name":"admin"}
13. 批量操作(复杂)
POST /_bulk
{"delete":{"_index":"test","_type":"user","_id":"10"}}
{"create":{"_index":"test","_type":"user","_id":"10"}}
{"name":"张三"}
{"index":{"_index":"test","_type":"user"}}
{"name":"李四"}
{"update":{"_index":"test","_type":"user","_id":"10"}}
{"doc":{"name":"法外狂徒:张三"}}
四、进阶操作
先导入一批官方测试数据
https://download.elastic.co/demos/kibana/gettingstarted/logs.jsonl.gz
https://download.elastic.co/demos/kibana/gettingstarted/accounts.zip
https://download.elastic.co/demos/kibana/gettingstarted/shakespeare_6.0.json
POST /bank/account/_bulk
以下测试使用的为accounts.zip数据,操作参考官方文档
- took :Elasticsearch运行查询所需的时间(以毫秒为单位)
- timed_out :搜索请求是否超时
- _shards :搜索了多少个分片,以及成功,失败或跳过了多少个分片。
- max_score :找到的最相关文件的分数
- hits.total.value :找到了多少个匹配的文档
- hits.sort :文档的排序位置(不按相关性得分排序时)
- hits._score:文档的相关性得分(使用时不适用match_all)
match_all查询所有
GET /bank/_search?q=*&sort=account_number:asc
GET /bank/_search?pretty
{
"query": { "match_all": {} },
"sort": [
{ "account_number": "asc" }
]
}
# query:match_all查询所有
# 排序:balance倒序,age正序(简写)
# from/size :从第几条开始,查询多少条(分页)
# _source:指定返回的字段名,未指定的不展示
GET /bank/_search
{
"query": {
"match_all": {}
},
"sort": [
{
"balance": {
"order": "desc"
}
},
{
"age":"asc"
}
],
"from": 5,
"size": 5,
"_source": ["balance","firstname"]
}
match全文检索
全文检索结果按照评分进行排序,对检索条件会进行分词匹配
GET /bank/_search
{
"query": {
"match": {
"balance": "49568"
}
}
}
GET /bank/_search
{
"query": {
"match": {
"address": "kings"
}
}
}
# mill lane会进行分词mill和lane两个词,只要匹配任意一个则会查询到
GET /bank/_search
{
"query": {
"match": {
"address": "mill lane"
}
}
}
match_phrase短语匹配
# mill lane不进行分词,必须包含mill lane的才能查到
GET /bank/_search
{
"query": {
"match_phrase": {
"address": "mill lane"
}
}
}
multi_match多字段匹配
# address或city中只要包含mill
GET /bank/_search
{
"query": {
"multi_match": {
"query": "mill",
"fields": ["address","city"]
}
}
}
# address或city中只要包含mill或者Brogan
GET /bank/_search
{
"query": {
"multi_match": {
"query": "mill Brogan",
"fields": ["address","city"]
}
}
}
bool复合查询
# must必须满足
# must_not必须不满足
# should应该,满不满足都可以,如果满足会使的评分要高
POST /_search?pretty
{
"query": {
"bool" : {
"must": [
{
"match": {
"gender": "M"
}
},
{
"match": {
"address": "mill"
}
}
],
"must_not": [
{
"match": {
"age": "28"
}
}
],
"should": [
{
"match": {
"firstname": "Forbes"
}
}
]
}
}
}
filter过滤
# 同样是查询年龄在10-20之间的数据,使用filter不会影响相关得分
POST /_search?pretty
{
"query": {
"bool" : {
"must": [
{
"range": {
"age": {
"gte": 10,
"lte": 20
}
}
}
]
}
}
}
POST /_search?pretty
{
"query": {
"bool" : {
"filter": [
{
"range": {
"age": {
"gte": 10,
"lte": 20
}
}
}
]
}
}
}
term查看
# 精确查询,主要用户差数字、金额、年龄等
GET /_search?pretty
{
"query": {
"term": {
"age": {
"value": "28"
}
}
}
}
# 每个字段都可以使用.keyword,完全匹配才能查询到(必须相等)
GET /bank/_search
{
"query": {
"match": {
"address.keyword": "198 Mill Lane"
}
}
}
aggregations聚合查询
# 查询address包含Mill的所有数据
# aggs对结果进行聚合,ageAggs,对聚合结果起别名
# terms表示按照age进行分组,返回10条记录
GET /bank/_search
{
"query": {
"match": {
"address": "Mill"
}
},
"aggs": {
"ageAggs": {
"terms": {
"field": "age",
"size": 10
}
}
}
}
# 查询address包含Mill的所有数据
# aggs对结果进行聚合,ageAggs/ageAvg/balanceAvg对聚合结果起别名
# terms表示按照age进行分组,返回10条记录
# avg 表示满足查询条件的所有数据中age/balance的平均值
# size 返回0条数据,只查询聚合结果
GET /bank/_search
{
"query": {
"match": {
"address": "Mill"
}
},
"aggs": {
"ageAggs": {
"terms": {
"field": "age",
"size": 10
}
},
"ageAvg":{
"avg": {
"field": "age"
}
},
"balanceAvg":{
"avg": {
"field": "balance"
}
}
},
"size": 0
}
# 查询所有数据
# 查询所有的年龄段
# 查询每个年龄段balance的平均值
GET /bank/_search
{
"query": {
"match_all": {}
},
"aggs": {
"ageAggs": {
"terms": {
"field": "age",
"size": 100
},
"aggs": {
"age-balance-avg": {
"avg": {
"field": "balance"
}
}
}
}
},
"size": 0
}
# 查询所有数据
# 查询所有的年龄段
# 查询每个年龄段balance的平均值
# 通过年龄段再按照性别区分,分别计算不同性别的群体的平均balance
GET /bank/_search
{
"query": {
"match_all": {}
},
"aggs": {
"ageAggs": {
"terms": {
"field": "age",
"size": 100
},
"aggs": {
"age-balance-avg": {
"avg": {
"field": "balance"
}
},
"gender-aggs":{
"terms": {
"field": "gender.keyword"
},
"aggs": {
"gender-balance-aggs": {
"avg": {
"field": "balance"
}
}
}
}
}
}
},
"size": 0
}
mapping映射
# 查询bank下所有映射
GET /bank/_mapping
# 新增索引并添加映射
# name映射类型为text,全文索引,会做分词查询
# age映射类型为integer
# email映射类型为keyword,表示精确匹配
PUT /my_index
{
"mappings": {
"properties": {
"name":{"type": "text"},
"age":{"type": "integer"},
"email":{"type": "keyword"}
}
}
}
# 对已有索引添加新的映射
# index默认为true,false表示不被索引,不能通过test_id进行查询
PUT /my_index/_mapping
{
"properties": {
"test_id":{
"type": "integer",
"index":false
}
}
}
# 修改已有的映射,无法更改现有字段的映射或字段类型。更改现有字段可能会使已经建立索引的数据无效。
# 如果需要更改字段映射,则需要创建具有正确映射一个新的索引和重新索引的数据,然后将数据重新索引到新索引中
# source为数据源
# dest为目标,需要先创建new_bank索引,字段和bank/account一样,字段类型等可以自行修改,例如:age为long可以修改为integer等
POST _reindex
{
"source": {
"index": "bank",
"type":"account"
},
"dest": {
"index": "new_bank"
}
}
分词
安装ik分词
官方文档:标准的分词器
# 标准的分词对英文分词比较友好,中文分词效果不理想
# standard:标准的分词,可以分成各个单词
POST /_analyze?pretty
{
"analyzer": "standard",
"text": "The 2 QUICK Brown-Foxes jumped over the lazy dog's bone."
}
# 对中文分词之后会变为一个个汉字,分词效果不理想
POST /_analyze?pretty
{
"analyzer": "standard",
"text": "好好学习天天向上"
}
安装ik分词:Elasticsearch单机版+ik分词中有介绍
# ik存在两种分词ik_max_word比ik_smart分的更细
POST /_analyze
{
"analyzer": "ik_smart",
"text": "好好学习天天向上"
}
POST /_analyze
{
"analyzer": "ik_max_word",
"text": "好好学习天天向上"
}
自定义扩展词库
将自定义词库存放在nginx内
- 安装nginx
- 新建文件用于存放自定义词库
# 在nginx外部挂载html文件内新建文件夹
mkdir es
# 进入刚新建的es文件夹,新建文本,将自定义分词写入此文件即可
vi fenci.txt
- 进入安装ik插件地址/mydata/elasticsearch/plugins/(和安装Elasticsearch是插件地址是一样的),进入该插件,进入config
- 编辑IKAnalyzer.cfg.xml,修改xml内以下配置项
# 修改前
<!--用户可以在这里配置远程扩展字典 -->
<!-- <entry key="remote_ext_dict">words_location</entry> -->
# 修改后
<!--用户可以在这里配置远程扩展字典 -->
<entry key="remote_ext_dict">http://192.168.0.130/es/fenci.txt</entry>
- 重启elasticsearch(docker restart 容器ID/name)
五、Elasticsearch Clients
官方地址:https://www.elastic.co/guide/en/elasticsearch/client/index.html