IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> Day03_谷粒商城(ElasticSearch篇)摘要 -> 正文阅读

[大数据]Day03_谷粒商城(ElasticSearch篇)摘要

一、说明

谷粒商城的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访问路径

over

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里面格式设置成json和text均不可,测试必须要去kibana里Dev Tools

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,  #from+size限定,完成分页功能;
  "_source":["balance"],  #指定要返回的字段
  "sort": [
    {
      "account_number": {  # 返回结果按哪个列排序
        "order": "desc"  # 降序
      }
    }
  ]
}

112)query/match匹配查询1

①如果是非字符串,会进行精确匹配。

GET bank/_search
{
  "query": {
    "match": {
      "account_number": 20  #返回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"
    }
  }
}

# 查询出的结果有"mill lane"(得分9.80),有只含mill的"mill road",也有只含lane的"lane tol",这种模糊匹配到的无非就是得分低一点

113)query/match匹配查询2

match_phrase:不拆分字符串进行检索

GET bank/_search
{
  "query": {
    "match_phrase": {
      "address": "mill road"   #就是说不要匹配只有mill或只有road的,要找能够匹配mill road一整个子串(结果是"990 Mill Road")
    }
  }
}

字段.keyword:必须全匹配上才检索成功

GET bank/_search
{
  "query": {
    "match_phrase": {
      "address".keyword: "mill road"   #就是说要和"mill road"完全equal,所以匹配不到
    }
  }
}

114)query/multi_math【多字段匹配】

GET bank/_search
{
  "query": {
    "multi_match": {  #前面的match仅指定了一个字段。
      "query": "mill road",
      "fields": ["state","address"]  #查找state和address里面有mill road字符串的
    }
  }
}

#会进行分词查询,也就是说state和address里面有mill road或只有mill或只有road字符串的都会匹配上

115)query/bool复合查询

  • must:必须达到must所列举的所有条件
  • must_not:必须不匹配must_not所列举的所有条件。
  • should:应该满足should所列举的条件。满足条件最好,不满足也可以,满足得分更高
GET bank/_search
{
   "query":{
        "bool":{   
             "must":[ #必须符合查询gender=m,并且address=mill的数据
              {"match":{"address":"mill"}},
              {"match":{"gender":"M"}}
             ]
         }
    }
}

GET bank/_search
{
  "query": {
    "bool": {  #查询gender=m,并且address=mill的数据,但是age不等于38的
      "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" #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": { # 查询出包含mill的
    "match": {
      "address": "Mill"
    }
  },
  "aggs": { #基于查询聚合
    "ageAgg": {  # 聚合的名字,随便起
      "terms": { # 看值的可能性分布
        "field": "age",
        "size": 10
      }
    },
    "ageAvg": { 
      "avg": { # 看age值的平均
        "field": "age"
      }
    },
    "balanceAvg": {
      "avg": { # 看balance的平均
        "field": "balance"
      }
    }
  },
  "size": 0  # 不看详情
}

{
  "took" : 2,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 4, // 命中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  //31岁的有61个,平均薪资是28312
          }
        },
        {
          "key" : 39,
          "doc_count" : 60,
          "ageAvg" : {
            "value" : 25269.583333333332  //39岁的有60个,平均薪资是25269
          }
        },
		..............
		..............
      ]
    }
  }
}

③查出所有年龄分布,并且这些年龄段中M的平均薪资和F的平均薪资以及这个年龄段的总体平均薪资
【基于年龄段[男人(平均薪资)]、[女人(平均薪资)]、[总体平均薪资]】

GET bank/_search
{
  "query": {
    "match_all": {}
  },
  "aggs": {
    "ageAgg": {
      "terms": {  #  看age分布
        "field": "age",
        "size": 100
      },
      "aggs": { # 子聚合
        "genderAgg": {
          "terms": { # 看gender分布
            "field": "gender.keyword" # 注意这里,文本字段应该用.keyword
          },
          "aggs": { # 子聚合
            "balanceAvg": {
              "avg": { # 男性的平均
                "field": "balance"
              }
            }
          }
        },
        "ageBalanceAvg": {
          "avg": { #age分布的平均(男女)
            "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, //31岁的有61个
          "doc_count" : 61,
          "genderAgg" : { //看31岁人群中性别分布
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : "M",  //31岁人群中男人有35个
                "doc_count" : 35,
                "balanceAvg" : {
                  "value" : 29565.628571428573  //31岁人群中男人有35个,平均薪资是29565
                }
              },
              {
                "key" : "F", //31岁人群中女人有26个
                "doc_count" : 26,
                "balanceAvg" : {
                  "value" : 26626.576923076922  //31岁人群中女人有26个,平均薪资是26626
                }
              }
            ]
          },
          "ageBalanceAvg" : {
            "value" : 28312.918032786885  //31岁人群中平均薪资28312
          }
        }
      ]
        .......//省略其他
    }
  }
}


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分词
介绍了软件Xshell5Xftp5的使用

//使用默认分词器测试:
GET _analyze
{
   "text":"我是中国人"
}


//使用ik分词器测试
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的笔记里面写的很清楚

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2021-07-28 07:53:02  更:2021-07-28 07:55:42 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/7 4:13:28-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码