一、说明
谷粒商城的ES的完整笔记 和 谷粒商城的ES的视频
关于dockers中es的挂载
docker run --name elasticsearch -p 9200:9200 -p 9300:9300 \
-e "discovery.type=single-node" \
-e ES_JAVA_OPTS="-Xms64m -Xmx512m" \
-v /mydata/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
-v /mydata/elasticsearch/data:/usr/share/elasticsearch/data \
-v /mydata/elasticsearch/plugins:/usr/share/elasticsearch/plugins \
-d elasticsearch:7.4.2
ElasticSearch访问路径

Kibana访问路径

二、增删改查
p105)检索es信息
对于ElasticSearch中的Get请求 的http://192.168.218.128:9200/_cat/nodes 我们简记为GET /_cat/nodes , GET /_cat/nodes :查看所有节点 GET /_cat/health :查看es健康状况 GET /_cat/master :查看主节点 GET/_cat/indicies :查看所有索引 ,等价于mysql数据库的show databases;
p106)新增&修改文档
①索引———类型————文档 类比于 数据库——数据表———数据
②可以是put亦可以是post: PUT customer/external/1 :在customer索引下的external类型下保存1号数据 POST customer/external/1 :在customer索引下的external类型下保存1号数据
http://192.168.56.10:9200/customer/external/1
{
"name":"John Doe"
}
③PUT和POST区别 POST。如果不指定id,会自动生成id。指定id就会修改这个数据,并新增版本号;
- 可以不指定id,不指定id时永远为创建
- 指定存在的id为更新,而版本号会根据内容变没变而决定版本号递增与否
PUT。PUT必须指定id;由于PUT需要指定id,我们一般用来做修改操作,不指定id会报错。
- 必须指定id
- 版本号总会增加(Put比较莽,哪里会对比数据啊)
p107)使用乐观锁更新文档
PUT http://192.168.56.10:9200/customer/external/1?if_seq_no=18&if_primary_term=6
乐观锁用法:通过“if_seq_no=1&if_primary_term=1 ”,当序列号匹配的时候,才进行修改,否则不修改。
_seq_no 是并发控制字段,每次更新都会+1,用来做乐观锁。 _primary_term 也是一个控制字段,当主分片重新分配(如重启),就会变化
p108)更新文档
Post带update:POST customer/externel/1/_update ,会对比原来的数据,数据如果和原来的相同,则(version和_seq_no)都不变。 Post不带update:POST customer/externel/1 ,总会重新保存并增加version版本。 Put不能带update: PUT customer/externel/1 ,总会重新保存并增加version版本。
p109)删除文档或索引
DELETE customer/external/1 删除哪个索引哪个类型下的哪个文档 DELETE customer 删除整个索引 虽然类型相当于数据库中的表,但是没有删除类型的操做
p109)ES的批量操作——bulk
POST /customer/external/_bulk 对哪个索引哪个类型做批量操作
POST http://192.168.56.10:9200/customer/external/_bulk
{"index":{"_id":"1"}}
{"name":"a"}
{"index":{"_id":"2"}}
{"name":"b"}
POST /_bulk 对于整个索引执行批量操作
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 updated blog post"}}
这里的批量操作,当发生某一条执行发生失败时,其他的数据仍然能够接着执行,也就是说彼此之间是独立的。 如果一个单个的动作失败,它将继续处理它后面剩余的动作。当bulk api返回时,它将提供每个动作的状态(与发送的顺序相同),所以您可以检查是否一个指定的动作是否失败了。
三、Es查询
p110)两种请求方式:
①请求参数方式检索:GET bank/_search?q=*&sort=account_number:asc ,其中GET bank/_search 表示检索bank下所有信息,包括type和docs;q=* 表示查询所有;sort=account_number 是排序字段排序字段;asc 表示升序
②uri+请求体进行检索(最常用的方式,这种方式被我们称为Query DSL语言)
GET /bank/_search
{
"query": { "match_all": {} },
"sort": [
{ "account_number": "asc" },
{ "balance":"desc"}
]
}
返回内容:
took – 花费多少ms搜索timed_out – 是否超时_shards – 多少分片被搜索了,以及多少成功/失败的搜索分片max_score –文档相关性最高得分hits.total.value - 多少匹配文档被找到hits.sort - 结果的排序key(列),没有的话按照score排序hits._score - 相关得分 (not applicable when using match_all)- 检索了1000条数据,但是根据相关性算法,只返回10条
111)Query DSL语言
GET bank/_search
{
"query": {
"match_all": {}
},
"from": 0,
"size": 5,
"_source":["balance"],
"sort": [
{
"account_number": {
"order": "desc"
}
}
]
}
112)query/match匹配查询1
①如果是非字符串,会进行精确匹配。
GET bank/_search
{
"query": {
"match": {
"account_number": 20
}
}
}
查询结果:
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 1.0, # 最大得分
"hits" : [
{
"_index" : "bank",
"_type" : "account",
"_id" : "20",
"_score" : 1.0,
"_source" : { # 该条文档信息
"account_number" : 20,
"balance" : 16418,
"firstname" : "Elinor",
"lastname" : "Ratliff",
"age" : 36,
"gender" : "M",
"address" : "282 Kings Place",
"employer" : "Scentric",
"email" : "elinorratliff@scentric.com",
"city" : "Ribera",
"state" : "WA"
}
}
]
}
}
②如果是字符串,会进行全文检索
GET bank/_search
{
"query": {
"match": {
"address": "mill lane"
}
}
}
113)query/match匹配查询2
match_phrase :不拆分字符串进行检索
GET bank/_search
{
"query": {
"match_phrase": {
"address": "mill road"
}
}
}
字段.keyword :必须全匹配上才检索成功
GET bank/_search
{
"query": {
"match_phrase": {
"address".keyword: "mill road"
}
}
}
114)query/multi_math【多字段匹配】
GET bank/_search
{
"query": {
"multi_match": {
"query": "mill road",
"fields": ["state","address"]
}
}
}
115)query/bool复合查询
- must:必须达到must所列举的所有条件
- must_not:必须不匹配must_not所列举的所有条件。
- should:应该满足should所列举的条件。满足条件最好,不满足也可以,满足得分更高
GET bank/_search
{
"query":{
"bool":{
"must":[
{"match":{"address":"mill"}},
{"match":{"gender":"M"}}
]
}
}
}
GET bank/_search
{
"query": {
"bool": {
"must": [
{ "match": { "gender": "M" }},
{ "match": {"address": "mill"}}
],
"must_not": [
{ "match": { "age": "38" }}
]
}
}
GET bank/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"gender": "M"
}
},
{
"match": {
"address": "mill"
}
}
],
"must_not": [
{
"match": {
"age": "18"
}
}
],
"should": [
{
"match": {
"lastname": "Wallace"
}
}
]
}
}
}
116)query/filter【结果过滤】
- must 贡献得分
- should 贡献得分
- must_not 不贡献得分
- filter 不贡献得分
- 上面的must和should影响相关性得分,而must_not和filter一样,就是个过滤器
GET bank/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"address": "mill"
}
}
],
"filter": {
"range": {
"balance": {
"gte": "10000",
"lte": "20000"
}
}
}
}
}
}
117)query/term
- term用法和match一样。但是有一个规范就是:文本字段text查询用
match ,其他非text字段(比如age、id什么的)匹配用term 。 - 因为term查询其实是精确匹配,es存储text值时用分词方式(这种方式不精确),所以要搜索text值,使用match。
GET bank/_search
{
"query": {
"term": {
"age": "28"
}
}
}
四、高级操作
p118)聚合操作
聚合操作看视频,非常地清除
- terms:看值的可能性分布,会合并锁查字段,给出计数即可
- avg:看值的分布平均
①搜索address中包含mill的所有人的(年龄分布、平均年龄、薪资分布),但不显示这些人的详情
GET bank/_search
{
"query": {
"match": {
"address": "Mill"
}
},
"aggs": {
"ageAgg": {
"terms": {
"field": "age",
"size": 10
}
},
"ageAvg": {
"avg": {
"field": "age"
}
},
"balanceAvg": {
"avg": {
"field": "balance"
}
}
},
"size": 0
}
{
"took" : 2,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 4,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
},
"aggregations" : {
"ageAgg" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : 38, # age为38的有2条
"doc_count" : 2
},
{
"key" : 28,
"doc_count" : 1
},
{
"key" : 32,
"doc_count" : 1
}
]
},
"ageAvg" : {
"value" : 34.0 # balance字段的平均值是34
},
"balanceAvg" : {
"value" : 25208.0
}
}
}
②查询所有人的(年龄分布(并且基于年龄分布求这些年龄段的这些人的平均薪资))
GET bank/_search
{
"query": {
"match_all": {}
},
"aggs": {
"ageAgg": {
"terms": {
"field": "age",
"size": 100
},
"aggs": {
"ageAvg": {
"avg": {
"field": "balance"
}
}
}
}
},
"size": 0
}
{
"took" : 49,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1000,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
},
"aggregations" : {
"ageAgg" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : 31,
"doc_count" : 61,
"ageAvg" : {
"value" : 28312.918032786885
}
},
{
"key" : 39,
"doc_count" : 60,
"ageAvg" : {
"value" : 25269.583333333332
}
},
..............
..............
]
}
}
}
③查出所有年龄分布,并且这些年龄段中M的平均薪资和F的平均薪资以及这个年龄段的总体平均薪资 【基于年龄段[男人(平均薪资)]、[女人(平均薪资)]、[总体平均薪资]】
GET bank/_search
{
"query": {
"match_all": {}
},
"aggs": {
"ageAgg": {
"terms": {
"field": "age",
"size": 100
},
"aggs": {
"genderAgg": {
"terms": {
"field": "gender.keyword"
},
"aggs": {
"balanceAvg": {
"avg": {
"field": "balance"
}
}
}
},
"ageBalanceAvg": {
"avg": {
"field": "balance"
}
}
}
}
},
"size": 0
}
{
"took" : 119,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1000,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
},
"aggregations" : {
"ageAgg" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : 31,
"doc_count" : 61,
"genderAgg" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : "M",
"doc_count" : 35,
"balanceAvg" : {
"value" : 29565.628571428573
}
},
{
"key" : "F",
"doc_count" : 26,
"balanceAvg" : {
"value" : 26626.576923076922
}
}
]
},
"ageBalanceAvg" : {
"value" : 28312.918032786885
}
}
]
.......
}
}
}
p119)—120)—121)Mapping字段映射
1.关于类型 以前是索引———类型————文档 类比于 数据库——数据表———数据 从7.0版本以后不再有"类型 "的说法了,文档就是直接存储在索引下面

2.关于Mapping字段映射
 
3.新加映射
基于上一步的age、email、name字段的映射,我们现在想要新加一个字段的映射时得这么做
PUT /my_index/_mapping
{
"properties": {
"employee-id": {
"type": "keyword",
"index": false
}
}
}
4.修改映射
不能更新映射:对于已经存在的字段映射,我们不能更新。更新必须创建新的索引,进行数据迁移。
有点麻烦,需要的话请看视频:p121修改映射与数据迁移
p122)分词
介绍了在linux里面安装es的分词器—安装ik分词 介绍了软件Xshell5 和Xftp5 的使用
GET _analyze
{
"text":"我是中国人"
}
GET _analyze
{
"analyzer": "ik_smart",
"text":"我是中国人"
}
p123)给vagrant配网
p124)ik分词之自定义分词器
我们装一个nginx,把自定义分词写到nginx的某个文件里,然后让ik分词器给nginx发送请求,拉取最新的词库
1.关于docker中nginx的安装与挂载
docker run -p 80:80 --name nginx \
-v /mydata/nginx/html:/usr/share/nginx/html \
-v /mydata/nginx/logs:/var/log/nginx \
-v /mydata/nginx/conf/:/etc/nginx \
-d nginx:1.10

2.自定义分词
在/mydata/nginx/html 就是你的nginx的自定义html页面的目录, 你在里面建了一个es目录存放es相关的配置,现在在/mydata/nginx/html/es下创建fenci.txt存放你要自定义的分词,里面写了“乔碧罗”和“尚硅谷” 然后修改ik的配置让它读取/mydata/nginx/html/es/fenci.txt ,这样ik就可以根据里面的自定义分词进行分词

五、SpringBoot整合ES
p125)SpringBoot整合Es
建议看完【尚硅谷】ElasticSearch的p49—p53讲了SpringBoot集成ES,再回来看这个视频。 这个在当初我做的ElasticSearch的笔记里面写的很清楚
p126)JavaAPI来操做ES1
p126讲的实际上就是【尚硅谷】ElasticSearch的p18—p28是用JavaAPI来编码操做ES,而且只讲了冰山一角,没必要去做什么笔记 这个在当初我做的ElasticSearch的笔记里面写的很清楚
p127)JavaAPI来操做ES2
p127讲的实际上就是【尚硅谷】ElasticSearch的p18—p28是用JavaAPI来编码操做ES,而且只讲了冰山一角,没必要去做什么笔记 这个在当初我做的ElasticSearch的笔记里面写的很清楚
|