Day407&408&409.ES -谷粒商城

Posted 阿昌喜欢吃黄桃

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Day407&408&409.ES -谷粒商城相关的知识,希望对你有一定的参考价值。

ES

一、基本概念

mysql用作持久化存储,ES用作检索

  • index索引

类比mysql的数据库概念

  • Type类型

类比mysql的概念

  • Document文档

类比mysql的记录概念

index库>type表>document文档

  • 为什么ES搜索快?倒排索引

检索:
1 红海特工行动?查出后计算相关性得分:3号记录命中了2次,且3号本身才有3个单词,2/3,所以3号最匹配
2 红海行动?

关系型数据库中两个数据表示是独立的,即使他们里面有相同名称的列也不影响使用,但ES中不是这样的。
elasticsearch是基于Lucene开发的搜索引擎,而ES中不同type下名称相同的filed最终在Lucene中的处理方式是一样的。

• 两个不同type下的两个user_name,在ES同一个索引下其实被认为是同一个filed,你必须在两个不同的type中定义相同的filed映射。
否则,不同type中的相同字段名称就会在处理中出现冲突的情况,导致Lucene处理效率下降。去掉type就是为了提高ES处理数据的效率。


Elasticsearch 7.x
URL中的type参数为可选。比如,索引一个文档不再要求提供文档类型。


Elasticsearch 8.x
不再支持URL中的type参数。


解决:
将索引从多类型迁移到单类型,每种类型文档一个独立索引

二、Docket安装ES

1、dokcer中安装elastic search

下载ealastic search(存储和检索)和kibana(可视化检索)

docker pull elasticsearch:7.4.2
docker pull kibana:7.4.2

注意版本要统一


2、配置

# 将docker里的目录挂载到linux的/usr/local/elasticsearch/data目录中,修改/mydata就可以改掉docker里的
mkdir -p /mydata/elasticsearch/config
mkdir -p /mydata/elasticsearch/data

# es可以被远程任何机器访问
echo "http.host: 0.0.0.0" >/mydata/elasticsearch/config/elasticsearch.yml

# 递归更改权限,es需要访问
chmod -R 777 /mydata/elasticsearch/

3、启动Elastic search

# 9200是用户交互端口 9300是集群心跳端口
# -e指定是单阶段运行
# -e指定占用的内存大小,生产时可以设置32G
sudo 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 

查看是否启动成功

docker ps


4、安装kibana

  • 拉去kibana,注意版本对应
docker pull kibana:7.4.2
  • 启动kibana
sudo docker run --name kibana -e ELASTICSEARCH_HOSTS=http://192.168.109.101:9200  -p 5601:5601 -d kibana:7.4.2

5、测试

  • 查看elasticsearch版本信息http://192.168.109.101:9200

  • 显示elasticsearch节点信息:http://192.168.109.101:9200/_cat/nodes

127.0.0.1 14 92 29 0.48 0.96 0.60 dilm * 4fe4e202abf1
#    4fe4e202abf1代表上面的结点 *代表是主节点
  • 访问Kibanahttp://192.168.109.101:5601/app/kibana


6、初步检索

  • _CAT
GET /_cat/nodes     #查看所有节点

127.0.0.1 15 93 8 0.18 0.55 0.52 dilm * 4fe4e202abf1
GET /_cat/health    #查看es健康状况

1633079094 09:04:54 elasticsearch green 1 1 3 3 0 0 0 0 - 100.0%
# 注:green表示健康值正常
GET /_cat/master    #查看主节点

Y9zawKrWSQWvFBx0wVi94g 127.0.0.1 127.0.0.1 4fe4e202abf1
# 主节点唯一编号
# 虚拟机地址
GET /_cat/indicies  #查看所有索引,等价于mysql数据库的show databases

green  open .kibana_task_manager_1   DhtDmKrsRDOUHPJm1EFVqQ 1 0 2 3 40.8kb 40.8kb
green  open .apm-agent-configuration vxzRbo9sQ1SvMtGkx6aAHQ 1 0 0 0   230b   230b
green  open .kibana_1                rdJ5pejQSKWjKxRtx-EIkQ 1 0 5 1 18.2kb 18.2kb
#这3个索引是kibana创建的
  • PUT

必须携带id

#索引一个文档
#保存一个数据,保存在哪个索引的哪个类型下(哪张数据库哪张表下),保存时用唯一标识指定

put /achang/user/1  #这里的1是指定了id为1
{
  "name":"achang",
  "age":"18"
}


{
  "_index" : "achang", #表明该数据在哪个数据库下
  "_type" : "user",    #表明该数据在哪个类型下
  "_id" : "1",         #表明被保存数据的id
  "_version" : 1,      #被保存数据的版本
  "result" : "created",#这里是创建了一条数据,如果重新put一条数据,则该状态会变为updated,并且版本号也会发生变化。
  "_shards" : { #分片,集群的情况下
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 0,       #并发控制字段,每次更新都会+1,用来做乐观锁
  "_primary_term" : 1  #主分片重新分配,如重启,就会变化
}

  • GET
get /achang/user/1

{
  "_index" : "achang",
  "_type" : "user",
  "_id" : "1",
  "_version" : 2,
  "_seq_no" : 1,
  "_primary_term" : 1,
  "found" : true,
  "_source" : { #真正的数据
    "name" : "achang",
    "age" : "20"
  }
}
  • 乐观锁

通过“if_seq_no=1&if_primary_term=1”,当序列号匹配的时候,才进行修改,否则不修改。

#如下两个请求并发发出
put /achang/user/1?if_seq_no=1&if_primary_term=1
{
  "name" : "achang1"
}

put /achang/user/1?if_seq_no=1&if_primary_term=1
{
  "name" : "achang2"
}

#再次查询,发现name被改成了achang1
get /achang/user/1
{
  "_index" : "achang",
  "_type" : "user",
  "_id" : "1",
  "_version" : 3,
  "_seq_no" : 2,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "name" : "achang1"
  }
}
  • _update
POST customer/externel/1/_update
{
    "doc":{
        "name":"111"
    }
}
#或者
POST customer/externel/1
{
    "doc":{
        "name":"222"
    }
}
#或者
PUT customer/externel/1
{
    "doc":{
        "name":"222"
    }
}

不同

  • 带有update情况下 POST操作会对比源文档数据,如果相同不会有什么操作,文档version不增加

  • PUT操作总会重新保存并增加version版本

  • POST时带_update对比元数据如果一样就不进行任何操作

看场景

  • 对于大并发更新不带update
  • 对于大并发查询偶尔更新带update;对比更新,重新计算分配规则
  • POST更新文档,带有_update
  • 删除文档或索引
DELETE customer/external/1
DELETE customer

#注:elasticsearch并没有提供删除类型的操作,只提供了删除索引和文档的操作。
#实例:删除整个costomer索引数据
#删除前,所有的索引
get /_cat/indices
green  open .kibana_task_manager_1   DhtDmKrsRDOUHPJm1EFVqQ 1 0 2 0 31.3kb 31.3kb
green  open .apm-agent-configuration vxzRbo9sQ1SvMtGkx6aAHQ 1 0 0 0   283b   283b
green  open .kibana_1                rdJ5pejQSKWjKxRtx-EIkQ 1 0 8 3 28.8kb 28.8kb
yellow open customer                 mG9XiCQISPmfBAmL1BPqIw 1 1 9 1  8.6kb  8.6kb

#删除 “customer”索引
DELTE /customer
#响应
{
    "acknowledged": true
}


#删除后,所有的索引/_cat/indices
green open .kibana_task_manager_1   DhtDmKrsRDOUHPJm1EFVqQ 1 0 2 0 31.3kb 31.3kb
green open .apm-agent-configuration vxzRbo9sQ1SvMtGkx6aAHQ 1 0 0 0   283b   283b
green open .kibana_1                rdJ5pejQSKWjKxRtx-EIkQ 1 0 8 3 28.8kb 28.8kb
  • ES的批量操作——bulk
#匹配导入数据
post /customer/external/_bulk
{"index":{"_id":"1"}}#两行为一个整体
{"name":"a"}#真正的数据
{"index":{"_id":"2"}}#两行为一个整体
{"name":"b"}#真正的数据
#语法格式:
post /xxxxx/xxxxx/_bulk
{action:{metadata}}\\n
{request body  }\\n
{action:{metadata}}\\n
{request body  }\\n

这里的批量操作,当发生某一条执行发生失败时,其他的数据仍然能够接着执行,也就是说彼此之间是独立的

bulk api以此按顺序执行所有的action(动作)。如果一个单个的动作因任何原因失败,它将继续处理它后面剩余的动作。当bulk api返回时,它将提供每个动作的状态(与发送的顺序相同),所以您可以检查是否一个指定的动作是否失败了。

#实例1: 执行多条数据
POST /customer/external/_bulk
{"index":{"_id":"1"}}
{"name":"John Doe"}
{"index":{"_id":"2"}}
{"name":"John Doe"}
#保存操作,指定了索引、id,真正的数据未name:xxx

#执行结果
{
  "took" : 318,  #花费了多少ms
  "errors" : false, #没有发生任何错误
  "items" : [ #每个数据的结果
    {
      "index" : { #保存
        "_index" : "customer", #索引
        "_type" : "external", #类型
        "_id" : "1", #文档
        "_version" : 1, #版本
        "result" : "created", #创建
        "_shards" : {
          "total" : 2,
          "successful" : 1,
          "failed" : 0
        },
        "_seq_no" : 0,
        "_primary_term" : 1,
        "status" : 201 #新建完成
      }
    },
    {
      "index" : { #第二条记录
        "_index" : "customer",
        "_type" : "external",
        "_id" : "2",
        "_version" : 1,
        "result" : "created",
        "_shards" : {
          "total" : 2,
          "successful" : 1,
          "failed" : 0
        },
        "_seq_no" : 1,
        "_primary_term" : 1,
        "status" : 201
      }
    }
  ]
}
#实例2:对于整个索引执行批量操作
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"}}
#指定操作,索引,类型,id


#运行结果:
{
  "took" : 414,
  "errors" : false,
  "items" : [
    {
      "delete" : {
        "_index" : "website",
        "_type" : "blog",
        "_id" : "123",
        "_version" : 1,
        "result" : "not_found",
        "_shards" : {
          "total" : 2,
          "successful" : 1,
          "failed" : 0
        },
        "_seq_no" : 0,
        "_primary_term" : 1,
        "status" : 404
      }
    },
    {
      "create" : {
        "_index" : "website",
        "_type" : "blog",
        "_id" : "123",
        "_version" : 2,
        "result" : "created",
        "_shards" : {
          "total" : 2,
          "successful" : 1,
          "failed" : 0
        },
        "_seq_no" : 1,
        "_primary_term" : 1,
        "status" : 201
      }
    },
    {
      "index" : {
        "_index" : "website",
        "_type" : "blog",
        "_id" : "AOpgO3wB3UIR4wi8SrO8",
        "_version" : 1,
        "result" : "created",
        "_shards" : {
          "total" : 2,
          "successful" : 1,
          "failed" : 0
        },
        "_seq_no" : 2,
        "_primary_term" : 1,
        "status" : 201
      }
    },
    {
      "update" : {
        "_index" : "website",
        "_type" : "blog",
        "_id" : "123",
        "_version" : 3,
        "result" : "updated",
        "_shards" : {
          "total" : 2,
          "successful" : 1,
          "failed" : 0
        },
        "_seq_no" : 3,
        "_primary_term" : 1,
        "status" : 200
      }
    }
  ]
}
  • 样本测试数据

准备了一份顾客银行账户信息的虚构的JSON文档样本。每个文档都有下列的schema(模式)。

{
	"account_number": 1,
	"balance": 39225,
	"firstname": "Amber",
	"lastname": "Duke",
	"age": 32,
	"gender": "M",
	"address": "880 Holmes Lane",
	"employer": "Pyrami",
	"email": "amberduke@pyrami.com",
	"city": "Brogan",
	"state": "IL"
}

https://gitee.com/xlh_blog/common_content/blob/master/es%E6%B5%8B%E8%AF%95%E6%95%B0%E6%8D%AE.json;导入测试数据

POST bank/account/_bulk
#上面的数据

get /_cat/indices #刚导入了1000条


  • 让Docker每次启动都自动启动ES

sudo docker update 【实例ID】 --restart=always

[root@s1 elasticsearch]# sudo docker ps -a
CONTAINER ID   IMAGE                 COMMAND                  CREATED       STATUS       PORTS                                                                                  NAMES
5c43fff82773   kibana:7.4.2          "/usr/local/bin/dumb…"   2 hours ago   Up 2 hours   0.0.0.0:5601->5601/tcp, :::5601->5601/tcp                                              kibana
4fe4e202abf1   elasticsearch:7.4.2   "/usr/local/bin/dock…"   2 hours ago   Up 2 hours   0.0.0.0:9200->9200/tcp, :::9200->9200/tcp, 0.0.0.0:9300->9300/tcp, :::9300->9300/tcp   elasticsearch
879b641ebe6c   redis                 "docker-entrypoint.s…"   11 days ago   Up 2 hours   0.0.0.0:6379->6379/tcp, :::6379->6379/tcp                                              redis
b2b889f90cd9   mysql:5.7             "docker-entrypoint.s…"   11 days ago   Up 2 hours   0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp                                   mysql
[root@s1 elasticsearch]# sudo docker update 5c4 --restart=always
5c4
[root@s1 elasticsearch]# sudo docker update 4fe --restart=always
4fe

三、进阶检索

官方API

https://www.elastic.co/guide/en/elasticsearch/reference/7.x/search-your-data.html

1、search Api

  • 通过REST request uri 发送搜索参数 (uri +检索参数);
  • 通过REST request body 来发送它们(uri+请求体);
  • 请求参数方式检索

检索bank索引中查询全部,并按account_number升序排序;

检索了1000条数据,但是根据相关性算法,只返回10条

GET bank/_search?q=*&sort=account_number:asc

# q=* 查询所有
# sort 排序字段
# asc升序 

检索bank下所有信息,包括type和docs

GET bank/_search

返回格式

took – 花费多少ms搜索
timed_out – 是否超时
_shards – 多少分片被搜索了,以及多少成功/失败的搜索分片
max_score –文档相关性最高得分
hits.total.value - 多少匹配文档被找到
hits.sort - 结果的排序key,没有的话按照score排序
hits._score - 相关得分 (not applicable when using match_all)

  • uri+请求体进行检索
GET /bank/_search
{
  "query": { "match_all": {} },
  "sort": [
    { "account_number": "asc" },
    {"balance":"desc"}
  ]
}

2、Query DSL

什么get的请求体叫query DSL

  • 基本语法格式

    Elasticsearch提供了一个可以执行查询的Json风格的DSL(domain-specific language领域特定语言)。这个被称为Query DSL,该查询语言非常全面。

    • 典型结构
    QUERY_NAME:{
       ARGUMENT:VALUE,
       ARGUMENT:VALUE,
        ...
    }
    

    如果针对于某个字段,那么它的结构如下:

    {
      QUERY_NAME:{
         FIELD_NAME:{
           ARGUMENT:VALUE,
           ARGUMENT:VALUE,...
          }   
       }
    }
    
    • 示例
    GET bank/_search
    {
      "query": {  #查询形式
        "match_all": {} #查询所有
      },
      "from": 0, #开始位置
      "size": 5, #显示数
      "_source":["balance"],#返回部分字段
      "sort": [ #排序
        {
          "account_number": {
            "order": "desc"
          }
        }
      ]
    }
    
    #   _source为要返回的字段
    

3、match匹配查询

  • 基本类型(非字符串),精确控制

    GET bank/_search
    {
      "query": {
        "match": {
          "account_number": "999"
        }
      }
    }
    

查询结果

{
  "took" : 8,
  "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" : "999",
        "_score" : 1.0,
        "_source" : 以上是关于Day407&408&409.ES -谷粒商城的主要内容,如果未能解决你的问题,请参考以下文章

408计算机统考科目知识整理

STM32F407第2章 ThreadX USBX协议栈介绍

408组成原理&操作系统知识整理

STM32F407&F429&H7的DSP教程第34章 滤波器基础知识

Codeforces Round #408 (Div. 2)ABCD

专栏必读(计算机组成原理题目题型总结)计理期末考试&408统考算机组成原必考题型总结