zoukankan      html  css  js  c++  java
  • ElasticSearch学习文档

    整个文档以及springboot代码整合在:https://gitee.com/ning-xinjie/es.git

    Linux多节点环境搭建整套教程(最好设置成桥接模式,我设置Nat模式,节点之间通讯不太好使,反正自己使用嘛,自己家的Ip肯定够用了):https://www.bilibili.com/video/BV1bA411b7vs

    我的博客配置,但是网线不用选择连接

    进入虚拟机后,使用su root转到root用户权限

    ifconfig 发现没有ip
    
    执行  dhclient(帮助我们生成一个未被使用的ip)
    
    
     vim /etc/sysconfig/network-scripts/ifcfg-ens33
    
    修改为如下:
    TYPE=Ethernet
    PROXY_METHOD=none
    BROWSER_ONLY=no
    BOOTPROTO=static
    DEFROUTE=yes
    IPV4_FAILURE_FATAL=no
    IPV6INIT=yes
    IPV6_AUTOCONF=yes
    IPV6_DEFROUTE=yes
    IPV6_FAILURE_FATAL=no
    IPV6_ADDR_GEN_MODE=stable-privacy
    NAME=ens33
    UUID=8d0345e4-8a86-4a76-8694-c6a2237b661d
    DEVICE=ens33
    ONBOOT=yes
    IPADDR=192.168.2.85
    NETMASK=255.255.255.0
    GATEWAY=192.168.2.1
    DNS1=119.29.29.29
    
    
    

    然后使用命令:systemctl restart network.service

    需要选择桥接模式哈,要不然,重启后ping个一万年,基本上等于ping不上

    如果还不行,

    将上方的

    BOOTPROTO=dbclinet

    ONBOOT=no

    ,重启一下,我就是这样回来就好了(然后再改回来)

    npm install -g cnpm --registry=https://registry.npm.taobao.org

    我的ip

    主机:192.168.2.62
    
    192.168.2.84
    192.168.2.85
    192.168.2.86
    
    主机:10.17.4.179
    10.17.4.174
    10.17.4.211
    

    docker使用安装mysql等,需要先关闭本地虚拟机防火墙,然后重启,在安装就不会run之后状态为exit了

    设置docker开机自启动:

    systemctl enable docker
    systemctl start docker
    

    设置docker镜像开机自启动:

    在 docker run 指令中加入 --restart=always
    
    如果创建时未指定 --restart=always ,可通过update 命令设置
    
    docker update --restart=always xxx
    
    查看防火墙状态
    service firewalld status
    关闭防火墙
    service firewalld stop
    
    需要重启后进行如下安装(否则run之后仍然exit)
    
    docker search mysql
    docker pull mysql:5.7.31
    运行容器
    docker run --name mysql01 --restart=always -e MYSQL_ROOT_PASSWORD=123456 -d -p 3306:3306 mysql:5.7.31
    
    
    docker run -itd --name redis01 -p 6379:6379 --restart=always redis --requirepass 123456
    
    

    https://blog.csdn.net/baidu_21349635/article/details/102738972

    了解docker中默认路径
    conf
    /etc/nginx/nginx.conf

    html
    /usr/share/nginx/html

    log
    /var/log/nginx

    启动临时容器
    docker run --name tmp-nginx-container -d nginx

    新建本地目录
    mkdir -p /docker/nginx/
    拷贝临时容器默认文件到默认路径
    docker cp tmp-nginx-container:/etc/nginx/nginx.conf /docker/nginx/nginx.conf
    docker cp -a tmp-nginx-container:/usr/share/nginx/html /docker/nginx
    同理拷贝,容器/etc/nginx/conf.d的default文件到本地/docker/nginx/conf.d下
    删除临时容器
    docker rm -f tmp-nginx-container

    重新映射容器启动
    docker run --name mynignx -e TZ="Asia/Shanghai" -d -p 80:80 -v /docker/nginx/html:/usr/share/nginx/html -v /docker/nginx/nginx.conf:/etc/nginx/nginx.conf -v /docker/nginx/conf.d:/etc/nginx/conf.d -v /docker/nginx/logs:/var/log/nginx nginx

    linux上后台运行jar包

    netstat -lnp|grep 8080
    
    kill -9 96829
    
    nohup java -jar ruoyi-admin.jar &
    
    tail -f nohup.out 查看运行情况
    
    /home/nxj/java-project/dist
    
    
    打开 /usr/local/nginx/conf/nginx.conf
    
    将nginx配置文件中:location
     root   /home/nxj/java-project/dist;
     
     重新加载一下配置文件/usr/local/nginx/sbin/nginx -s reload
    

    将虚拟机端口暴露出来!!

    本地虚拟机可以访问自己安装的nginx但是主宿机却不行:

    【正常暴露80就行了,我们通过nginx访问其他的,但是现在好多我还不会...,先单独暴露网站进行访问】

    /sbin/iptables -I INPUT -p tcp --dport 80 -j ACCEPT 
    
    /sbin/iptables -I INPUT -p tcp --dport 8080 -j ACCEPT 
    

    GitHub相关

    Github报certificate verify locations的CApath为none的解决办法

    git config --system http.sslcainfo "D:MySoftwareGitGitetcpkica-trustextractedopensslca-bundle.trust.crt"

    Github访问过慢

    ElasticSearch

    Docker安装部署elasticsearch

    https://blog.csdn.net/daidai_min/article/details/107515279

    /var/lib/docker/containers/6b5d78d07940fa118beb9ceebd958516b06aac586ae3ca7788d95983e81fc97c

    /opt/

    href="https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.11.2-linux-x86_64.tar.gz"

    直接使用非root用户登录,并上传解压,那么这个用户就具有这个权限了,否则需要下方的命令,通过root将全线赋予给这个用户
    

    创建用户

    [最好设置个密码,我们使用es登陆,然后上传压缩包然后解压]

    groupadd es
    useradd es -g es
    chown -R es:es ./elasticsearch-6.4.2  #如果不是当前es用户上传及操作的,需要通过这个赋予它权限
    

    添加权限

    chown -R es:es /opt/elasticsearch

    chown -R es:es /opt/elasticsearch/kibana-7.7.0-linux-x86_64

    cd /opt/elasticsearch/kibana/bin
    
    su es
    
    ./kbania
    
    

    关闭防火墙

    systemctl stop firewalld
    systemctl disable firewalld  #永久禁用
    

    ES配置文件书写要求

    每个配置行前需要有空格

    每个‘:’两边需要有空格

    数组中间加空格

    还有注释掉的参数不能在#后边加空格不然报错

    开启es的远程连接权限

    【先关闭防火墙...【云服务器记得开启9200与9300端口】】
    
    需要修改在config下的elasticsearch.yml
    
    
    network下的 network.host: 0.0.0.0
    (在搭建集群的时候发现写 network.bind_host: 0.0.0.0 是允许远程访问)
    
    然后启动es出现如下错误:
    	切换到root用户进行以下操作
     ERROR: [3] bootstrap checks failed
    [1]: max file descriptors [4096] for elasticsearch process is too low, increase to at least [65535]
    
    	# vim /etc/security/limits.conf 
    		在文件末尾添加(星号也是要的):
    *               soft    nofile          65536
    *               hard    nofile          65536
    *               soft    nproc           4096
    *               hard    nproc           4096
    	(退出所有用户,重新登陆【将所有连接全部关掉】)
    		然后登陆,通过root查看配置是否生效:
    ulimit -Hn
    ulimit -Sn
    ulimit -Hu
    ulimit -Su
    
    
    [2]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]
    
    	#vim /etc/sysctl.conf 
    	在文件末尾添加:
    vm.max_map_count=262144
    执行/sbin/sysctl -p 立即生效
    
    [3]: the default discovery settings are unsuitable for production use; at least one of [discovery.seed_hosts, discovery.seed_providers, cluster.initial_master_nodes] must be configured
    
        在 elasticsearch.yml 配置文件中 添加:
        cluster.initial_master_nodes: ["node-1"]
        
        
    还有可能会报Thread的什么错:
    	# vim /etc/security/limits.d/20-nproc.conf 
    加上 es         soft    nproc     4096
    【其中es是登陆elasticsearch的用户】
    

    ES后台启动与停止

    ./elasticsearch -d
    
    
    使用jps查看java进程(因为elasticsearch是java开发的)
    
    [es@nxj-01 bin]$ jps
    10407 Elasticsearch
    10488 Jps
    [es@nxj-01 bin]$ kill 10407
    
    

    修改es的内存占用

    在config下jvm.options中修改
    
    最小改为512m,否则运行将会卡顿
    

    【ES只识别json格式!】

    • index
      • type
        • mapping

    索引 index

    拥有几分相似特征的文档的集合
    索引必须全部是小写的英文字母
    我们要对这个索引中的文档进行索引、搜索、更新和删除的时候,都要使用到这个名字。
    对索引中的文档进行CRUD是需要使用索引名称
    
    es的索引类似于mysql的数据库,但是它是一个相似特征文档的集合
    

    类型 type

    es5.X中一个索可以有多个类型,类型是索引的一个逻辑上的分区
    
    ES6.x以上一个索引只能对应一个类型。 (√)
    

    映射 mapping

    用来限定类型中的数据结构(包含哪些字段,字段的类型是什么)
    
    我们可以手动的创建mapping
    默认配置下,ES可以根据我们插入的数据自动的创建type及mapping,mapping中主要包括字段名、字段类型和字段索引
    

    文档 document(_doc)

    一个文档是一个可被索引的基础信息单元,类似于表中的一条记录
    文档以json表示。
    

    Kibana

    安装

    直接下载,解压,赋予es用户权限即可
    
     find / -name kibana.yml #查找位置(当然我们自己下载的,当然知道在哪里了,config下的kibana.yml)
    

    后台启动

    nohup ./kibanne &
    

    连接ES

    打开kibana.yml 修改如何配置
    
    server.host: "192.168.2.84"
    
    elasticsearch.hosts: ["http://192.168.2.84:9200"]
    

    下面的图片是6.X版本改的,我7.X改的是上方的hosts

    image-20210321164934009

    索引基本操作

    创建索引 put /索引名
    查看单个索引 get /索引名
    删除索引 delete /索引名
    删除所有索引 delete /*
    查看索引信息 GET /_cat/indices?v
    

    ES的Mapping类型

    text		#大文本
    keyword		#数据量较少的时候用
    date
    integer
    long
    double
    boolean
    ip
    

    类型映射基本操作

    文档地址:https://www.elastic.co/guide/en/elasticsearch/reference/7.7/index.html

    中REST APIS下的Document APIS

    创建/ems索引同时创建类型(映射规则)
    因为7.X之后一个索引对应一个类型,因此直接在mappings下写类型映射就好
    PUT /ems
    {
      "mappings": {
        "properties": {
            "id":    { "type": "keyword"  }, 
            "name":     { "type": "keyword"  }, 
            "age":      { "type": "integer" },  
            "created":  {
              "type":   "date", 
              "format": "strict_date_optional_time||epoch_millis"
            }
        }
      }  
    }
    
    #通过如下查看索引的类型映射规则
    GET /ems/_mapping
    
    @设置索引及映射规则
    PUT /dangdang 
    {
      "mappings": {
        "properties": {
          "id" :  {"type": "keyword"},
          "name":{"type" : "keyword"},
          "price":{"type": "double"},
          "counts":{"type": "integer"}
        }
      }
    }
    
    @查看索引映射规则
    GET /dangdang/_mapping
    
    @插入数据
    PUT /dangdang/_doc/1
    {
      "id":"21",
      "name":"iphone11",
      "price":4900,
      "counts": 15
    }
    
    @获取数据
    GET /dangdang/_doc/1
    
    @啊ES插入数据默认会按照如上方1去创建一个_id,因此我们存数据的时候内部没必要的话,不用再写一个id字段了
    

    更新部分指定字段

    POST /dangdang/_update/1
    {  
       "doc":{
         "age":32
       }
    }
    
    #设置price字段数值减少20
    POST /dangdang/_update/1
    {  
         "script":"ctx._source.price -= 20"
    }
    POST /ems/_update/1
    {  
       "script":"ctx._source.content += 'Spring'"
    }
    

    删除索引中的某个字段

    POST /dangdang/_update/1
    {  
         "script":"ctx._source.remove('name')"
    }
    

    删除索引中某条文档

    DELETE /dangdang/_doc/1
    

    批量操作

    文档地址:https://www.elastic.co/guide/en/elasticsearch/reference/7.7/docs-bulk.html
    
    
    POST _bulk
    { "index" : { "_index" : "dangdang","_id" : "1" } }
    { "field1" : "value1" }
    { "index" : { "_index" : "dangdang","_id" : "2" } }
    { "field1" : "value1" }
    { "delete" : { "_index" : "dangdang", "_id" : "2" } }
    { "update" : { "_index" : "dangdang", "_id" : "1" } }
    { "doc" : {"field2" : "value2", "field1" : "value4"} }
    { "create" : { "_index" : "dangdang", "_id" : "3" } }
    { "field1" : "value3" }
    
    GET /dangdang/_doc/1
    GET /dangdang/_doc/2
    GET /dangdang/_doc/3
    
    某一个失败,不会影响会后继续执行(已经试过了,即每个操作都是独立的,某条失败则继续则继续执行后面的)
    
    create:创建,如果有则失败
    index:是如果有则覆盖,没有则创建
    update:更新某个索引对应_id记录的值
    delete:删除某个索引对应_id记录的值
    

    ES中高级检索

    文档地址:https://www.elastic.co/guide/en/elasticsearch/reference/7.7/search-search.html

    测试

    建立索引结构
    PUT /ems 
    {
      "mappings": {
        "properties": {
          "name":{"type" : "keyword"},
          "age":{"type": "integer"},
          "birth":{"type": "date"},
          "content":{"type": "text"},
          "address":{"type": "keyword"}
        }
      }
    }
    
    
    插入测试数据
    POST _bulk
    { "index" : { "_index" : "ems","_id" : "1" } }
    { "name" : "张三", "age" : 25, "birth" : "2012-12-12", "content" : "一直以来,已经接近八旬的拜登其精神状态一直就为人诟病,所以这项民意调查也迅速引发了美国民众间的广泛讨论。毕竟一直都有人笑话拜登是美国历史上最年长的总统。再加上拜登经常出现的一些口误,甚至经常忘记一些重要的事情,这些都加剧了外界对其精神疾病的怀疑。有关拜登患有健忘症以及丧失行为能力等精神疾病的传言也就被外界广泛传播开来。", "address" : "北京" }
    { "index" : { "_index" : "ems","_id" : "2" } }
    { "name" : "李四", "age" : 24, "birth" : "2012-12-12", "content" : "久前,当我和哈里斯总统在线上参观亚利桑那州的疫苗中心时,其中一个负责疫苗接种工作的护士称,(她们)每打出一针就像是送出了一点希望。”这是拜登近日在庆祝美国疫苗接种工作时说的一段话,值得注意的是,在拜登的这次发言中他竟然口误,将美国副总统哈里斯称之为“总统”。", "address" : "天津" }
    { "index" : { "_index" : "ems","_id" : "3" } }
    { "name" : "王五", "age" : 26, "birth" : "2012-12-12", "content" : "在拜登发生这次口误之后,美国前总统特朗普的儿子小特朗普也迅速在其社交平台上转发了拜登口误的视频,并配文讽刺道:他竟然连最基本的(事情)都搞不清!", "address" : "大连" }
    { "index" : { "_index" : "ems","_id" : "4" } }
    { "name" : "吴六", "age" : 45, "birth" : "2012-12-12", "content" : "对78岁的拜登来说,想不起自己内阁官员的名字已是家常便饭,然而这一次,他竟然称呼哈里斯为“总统”。更加讽刺的是,就在近日一项美国民意调查中显示,有不少美国人都认为,在白宫进行重要日常决策的人不是拜登,甚至还有不少人认为是哈里斯在幕后作出重要决定", "address" : "上海" }
    { "index" : { "_index" : "ems","_id" : "5" } }
    { "name" : "马七", "age" : 75, "birth" : "2012-12-12", "content" : "据环球网援引近日俄罗斯的报道称,近日美国民调调查机构拉斯穆森最近进行了一项民意调查。结果显示,在受访者中有47%的人认为,实际上一直都是美国副总统哈里斯或者是其他官员在幕后作出的一系列决定;另外也有同样47%的受访者认为是拜登在履行总统的职责", "address" : "杭州" }
    

    查询所有 match_all

    GET /ems/_search?q=*
    
    查询所有并按照年龄降序并从第二页开始返回前两条(url写法)
    GET /ems/_search?q=*&sort=age:desc&size=2&from=2
    
    手动排序后,分数将无效,返回得分全部为null
    

    重点使用DSL方式检索:

    https://www.elastic.co/guide/en/elasticsearch/reference/7.7/search-search.html

    // 查询所有
    GET /ems/_search
    {
        "query" : {
            "match_all": {}
        }
    }
    
    // 查询所有并按照年龄降序并从第二页开始返回前两条(DSL写法)
    【一页放两个,0代表第一页,1代表size下移一位,2代表size下移两位】
    【这里size为2,那么2是第二页,4是第三页】
    
    _source指定我要查找的字段,默认是全部
    GET /ems/_search
    {
        "query" : {
            "match_all": {}
        },
        "_source": ["name","address","age"], 
        "size": 2,
        "sort": [
          {
            "age": {
              "order": "desc"
            }
          }
        ], 
        "from": 2
    }
    
    
    
    

    关键字查询 term

    除了text类型外的所有类型均不分词(将整体放入索引库中国)
    
    默认使用的是标准分词器(对于英文是单词分词,对于中文是单字分词【对于中文很不友好】)
    
    GET /ems/_search
    {
      "query": {
        "term": {
          "content": {
            "value": "美"
          }
        }
      }
    }
    
    GET /ems/_search
    {
      "query": {
       "term": {
         "content": {
           "value": "spring"
         }
       }
      }
    }
    

    范围查询range

    GET /ems/_search
    {
      "query": {
        "range": {
          "age": {
            "gte": 25,
            "lte": 50
          }
        }
      }
    } 
    

    前缀查询 prefix

    GET /ems/_search
    {
      "query": {
        "prefix": {
          "name": {
            "value": "吴"
          }
        }
      }
    }
    

    通配符查询 wildcard

    // ? 一个任意字符  
    // * 零或任意多个任意字符
    GET /ems/_search
    {
      "query": {
        "wildcard": {
          "content": {
            "value": "国*"
          }
        }
      }
    }
    
    GET /ems/_search
    {
      "query": {
        "wildcard": {
          "name": {
            "value": "张?"
          }
        }
      }
    }
    

    多id查询 ids

    GET /ems/_search
    {
      "query": {
        "ids": {
          "values": ["1", "2"]
        }
      }
    }
    

    模糊查询 fuzzy

    https://www.elastic.co/guide/en/elasticsearch/reference/7.7/query-dsl-fuzzy-query.html

    0..2

    Must match exactly

    3..5

    One edit allowed

    >5

    Two edits allowed

    0~2个之内的词必须完全匹配

    3~5允许错误一个

    长度大于5的词允许错误两个

    针对于name:孔给呃
    
    GET /ems/_search
    {
        "query": {
            "fuzzy": {
                "name": {
                    "value": "孔给s"
                }
            }
        }
    }
    
    如果写 孔给 即长度不满足,那么找不到!
    
    

    布尔查询 bool

    must: 相当于 and

    should: 相当于 or

    must_not: 相当于 not

    must内条件必须全部满足
    must_not内条件必须全部不满足
    GET /ems/_search
    {
      "query": {
        "bool": {
          "must": [
            {"term": {
              "content": {
                "value": "美"
              }
            }},
             {"term": {
              "content": {
                "value": "国"
              }
            }}
          ],
          "should": [
             {"wildcard": {
              "name": {
                "value": "王*"
              }
            }}
          ],
          "must_not": [
           {"wildcard": {
              "name": {
                "value": "李*"
              }
            }}
          ]
        }
      }
    }
    
    

    是一个多文档分词查询,比如下方的美国,先按照美,再按照国,如果都包含则的分最高

    对于name是keyword类型的,它不分词,因此匹配name时直接不分词,使用【美国】整体去找,对于content是text类型的,它分词,因此先对【美国】进行分词,在进行查找

    二者的结果进行合并(也就是多字段查询,互不影响【我查询结果是这样显示的】)

    GET /ems/_search
    {
      "query": {
        "multi_match": {
          "query": "美国",
          "fields": ["content","name"]
        }
      }
    }
    

    多字段分词查询 query_string

    先分词,按照分词条件去指定字段中搜索

    可以指定使用哪种分词器

    GET /ems/_search
    {
      "query": {
        "query_string": {
           "fields": ["content","name"],
          "query": "美国",
          "analyzer": "standard"
        }
      }
    }
    

    查询关键字高亮显示

    fields是将查询结果出来后的那些字段匹配分词的高亮

    【默认帮助我们加em标签,我们可以自定义,通过如下】

    pre_tags高亮前自定义标签

    post_tags高亮后自定义标签

    GET /ems/_search
    {
      "query": {
        "term": {
          "content": {
            "value": "美"
          }
        }
      },
      "highlight": {
        "fields": {"content": {},"address": {}},
        "pre_tags": ["<span style='color:red'>"],
        "post_tags": ["</span>"]
      }
    }
    
    
    GET /ems/_search
    {
      "query": {
         "query_string": {
           "fields": ["content","name"],
          "query": "美国",
          "analyzer": "standard"
        }
      },
      "highlight": {
        "fields": {"*": {}},
        "require_field_match": false,
        "pre_tags": ["<span style='color:red'>"],
        "post_tags": ["</span>"]
      }
    }
    
    
    GET /ems/_search
    {
      "query": {
         "query_string": {
           "fields": ["content","name"],
          "query": "小美"
        }
      },
      "highlight": {
        "fields": {"*": {}},
        "pre_tags": ["<span style='color:red'>"],
        "post_tags": ["</span>"]
      }
    }
    
    "fields": {"*": {}} 不太好用
    

    ES过滤查询

    Filter Query 效率高于查询【因为query需要计算得分并排序等等,而filter中的query直接告诉你数据是什么,其他的什么也不管,并且可以缓存文档

    使用filter query与query DSL 必须使用bool

    当filterQuery与query组合使用时,先执行filter中的query

    在应用时,先使用过滤操作过滤数据,在使用查询匹配数据

    ·有filter会先执行filter·
    
    GET /ems/_search
    {
      "query": {
        "bool": {
          "must": [
            {
              "term": {
                "content": "美国"
              }
            }
          ],
          "filter": [
            {
              "range": {
                "age": {
                  "gte": 25
                }
              }
            }
          ]
        }
      },
      "_source": ["name", "content"]
    }
    

    filter下还有query,和上方query使用一致

    ES索引底层大致原理

    image-20210322131222770

    分词器

    拆分关键词。去掉停用词和语气词

    es默认提供的分词器:

    1. standard 英文:单词分词 中文:单字分词
    2. simple 英文:单词分词,去掉数字 中文:不分词

    测试分词器

    GET _analyze
    {
      "analyzer": "standard",
      "text": ["这是一个分词器,Spring"]
    }
    
    GET _analyze
    {
      "analyzer": "simple",
      "text": ["这是一个分词器,Spring"]
    }
    

    IK分词器安装

    必须与ES版本严格一致

    id文档:https://github.com/medcl/elasticsearch-analysis-ik

    https://github.com/medcl/elasticsearch-analysis-ik/releases/tag/v7.8.1 直接下载(这个是已经打包好的了)

    1. 在线安装(自己百度,一行命令)
    2. 本地安装
      1. 上传下载的zip包到linux中
      2. mv elasticsearch-analysis-ik-7.8.1.zip /opt/elasticsearch/elasticsearch-7.8.1/plugins/ik/ (当然首先在唉在plugins下建一个ik目录)
      3. unzip elasticsearch-analysis-ik-7.8.1.zip elasticsearch-7.8.1/plugins/ik
      4. 重启ES
        1. jps找到进程
        2. kill 掉
        3. 然后再次启动
          1. cd /opt/elasticsearch/elasticsearch-7.8.1/bin/
          2. su es
          3. ./elasticsearch -d

    测试IK分词器

    ik_smart 
    ik_max_word
    
    ik_max_word: 会将文本做最细粒度的拆分,比如会将“中华人民共和国国歌”拆分为“中华人民共和国,中华人民,中华,华人,人民共和国,人民,人,民,共和国,共和,和,国国,国歌”,会穷尽各种可能的组合,适合 Term Query;
    
    ik_smart: 会做最粗粒度的拆分,比如会将“中华人民共和国国歌”拆分为“中华人民共和国,国歌”,适合 Phrase 查询。
    
    GET _analyze
    {
      "analyzer": "ik_max_word",
      "text": ["这是一个分词器,Spring"]
    }
    
    

    建立索引使指定使用ik分词器规则进行存储

    只有text支持分词,其余的都不支持,如果对于非text使用分词时,索引创建失败。

    PUT /ems 
    {
      "mappings": {
        "properties": {
          "name":{"type" : "text", "analyzer":"ik_max_word"},
          "age":{"type": "integer"},
          "birth":{"type": "date"},
          "content":{"type": "text", "analyzer":"ik_max_word"},
          "address":{"type": "keyword"}
        }
      }
    }
    

    自定义扩展词

    在ik/config/IKAnalyzer.cfg.xml 配置文件中扩展字典

    整个配置文件如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
    <properties>
            <comment>IK Analyzer 扩展配置</comment>
            <!--用户可以在这里配置自己的扩展字典 -->
            <entry key="ext_dict">ext.dict</entry>
             <!--用户可以在这里配置自己的扩展停止词字典-->
            <entry key="ext_stopwords"></entry>
            <!--用户可以在这里配置远程扩展字典 -->
            <!-- <entry key="remote_ext_dict">words_location</entry> -->
            <!--用户可以在这里配置远程扩展停止词字典-->
            <!-- <entry key="remote_ext_stopwords">words_location</entry> -->
    </properties>
    
    

    修改下方:

    <!--用户可以在这里配置自己的扩展字典 -->
    
    <entry key="ext_dict">ext.dict</entry>
    

    IK要求编码都是UTF-8的,为了防止自己touch 的文件不是UTF-8编码的,我们直接在config下有许多dict结尾的文件,拷贝一个改成我们自己的名字就好

    cp stopword.dic ext.dict

    vim进去后dG 删除全部

    加上测试的

    碰瓷
    宁新杰
    程序杰杰
    

    然后重启ES,测试

    GET _analyze
    {
      "analyzer": "ik_max_word",
      "text": ["我是宁新杰","哈哈 你好啊程序杰杰"]
    }
    

    生效!

    自定义停用词

             <!--用户可以在这里配置自己的扩展停止词字典-->
             <entry key="ext_stopwords">stopext.dic</entry>
    

    比如我将【混蛋】这个词放入stopext.dic , 那么如下因为这个词满足停用要求,则直接不会为它建立索引

    GET _analyze
    {
      "analyzer": "ik_max_word",
      "text": ["混蛋"]
    }
    

    配置远程扩展字典

    这个配置只能针针对于新增的生效,对于已经建立索引的仍然不会生效!

    1. 新建一个springboot项目,选择web模块,在static下建立remote_word.dic 写入扩展分词

    2.  <!--用户可以在这里配置远程扩展字典 -->
       <entry key="remote_ext_dict">http://192.168.2.62:8080/remote_word.dic</entry>
      
    3. 启动springboot

    4. 有可能虚拟机安全策略不允许直接访问ip(我们还需要为ip配置域名)

      1. vim /etc/hosts
      2. 192.168.2.62 nxj
    5.  <!--用户可以在这里配置远程扩展字典 -->
       <entry key="remote_ext_dict">http://nxj:8080/remote_word.dic</entry>
      
    6. 重启ES

    7. 测试
      GET _analyze
      {
        "analyzer": "ik_max_word",
        "text": ["空色是收到 你的我啊"]
      }
      

    或者修改安全组策略

    (我的虚拟机没有这个问题,如下的配置文件下为)

    我的这个配置文件下全允许
    grant codeBase "file:${jnlpx.home}/javaws.jar" {
        permission java.security.AllPermission;
    };
    
    @找到jre位置
    find / -name java
    
    cd /usr/local/java/jdk1.8.0_281/jre/lib/security
    
    vim javaws.policy 
    加入如下配置
    

    整合SpringBoot

    定义一个es的配置类

    @Configuration
    @EnableConfigurationProperties(ElasticSearchProperties.class)
    public class ElasticSearchConfig  {
    
        @Bean
        public RestHighLevelClient restHighLevelClient(ElasticSearchProperties esProperties){
    
            HttpHost[] httpHosts = new HttpHost[esProperties.getClusterSize()];
            for (int i = 0; i < httpHosts.length; i++) {
                httpHosts[i] = new HttpHost(esProperties.getHostname().get(i), esProperties.getPort().get(i), esProperties.getScheme().get(i));
            }
            return new RestHighLevelClient(RestClient.builder(httpHosts));
            // return new RestHighLevelClient(
            //         RestClient.builder(
            //                 new HttpHost("localhost", 9200, "http"),
            //                 new HttpHost("localhost", 9201, "http")));
        }
    }
    

    自定义properties可扩展(当然可以用它的,我先测试自己完成这个简单的小功能)

    @ConfigurationProperties("my.elastic")
    @Data
    public class ElasticSearchProperties {
    
        public int clusterSize;
        public List<String> hostname;
        public List<Integer> port;
        public List<String> scheme;
    }
    

    yml

    my:
      elastic:
        clusterSize: 1
        hostname: [10.17.4.174]
        port: [9200]
        scheme: [http]
    

    在test下测试

        @Autowired
        @Qualifier("restHighLevelClient")
        RestHighLevelClient esClient;
    
    
        @Test
        void contextLoads() throws IOException {
            SearchRequest searchRequest = new SearchRequest();
            esClient.search(searchRequest, RequestOptions.DEFAULT);
        }
    

    创建索引

        @Test
        void esIndex() throws IOException {
            // 创建索引请求
            CreateIndexRequest createIndexRequest = new CreateIndexRequest("nxj");
            // 执行创建请求,请求创建后获得请求
            CreateIndexResponse createIndexResponse = esClient.indices().create(createIndexRequest, RequestOptions.DEFAULT);
    
            System.out.println(createIndexResponse);
        }
    

    查询(_search)

        // !!!查询
        @Test
        void esSearch() throws IOException {
            SearchRequest searchRequest = new SearchRequest("ems");
            // 构建搜索条件
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    
            // term查询
            //TermQueryBuilder content = QueryBuilders.termQuery("content", ",美国");
    
    
            MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
    
            searchSourceBuilder.query(matchAllQueryBuilder);
            searchSourceBuilder.query(QueryBuilders.termQuery("content", "78"));
            searchSourceBuilder.postFilter(QueryBuilders.termQuery("content", "美国")); // 过滤会在es中先执行
    
            //searchSourceBuilder.size(6);
            //searchSourceBuilder.from(1);
    
            searchRequest.source(searchSourceBuilder);
            // 将结果打印出来
            SearchResponse search = esClient.search(searchRequest, RequestOptions.DEFAULT);
            SearchHit[] hits = search.getHits().getHits();
            for (SearchHit hit : hits) {
                System.out.println(hit.getSourceAsString());
            }
        }
    

    ES集群搭建

    为什么要搭建ES集群

    • 单点宕机,整个服务不可用
    • 请求过多,响应变慢
    • 数据过多,同一台服务器存不下

    ES集群组织架构

    每个节点存放部分数据,整个集群存储完整数据

    • 每个集群有唯一的名字,默认是elasticsearch 【生产环境建议显示指定】
    • 每个节点有唯一的名字,默认是随机的漫威漫画角色名字

    一个节点可以通过配置集群名称的方式来加入到一个指定的集群

    分片和复制(副本)

    分片就是:1TB数据 分成0.3T 0.3T 0.4T 这些就是分片,分片分别在不同服务器上存储

    副本就是分片的副本,为了防止主分片的服务器宕机导致数据丢失,我们一般会使用副本拷贝这些数据,存放在其它服务器上

    Q> 进入到elasticsearch-head目录下

    设置淘宝镜像

    ​ npm install --registry=https://registry.npm.taobao.org

    npm install

    npm run start

    【在寝室的时候因为是校园网,我又是桥接模式,因此虚拟机连不上网(因为校园网的账号只有一个嘛...我是这个觉得的)】【好在这个系统打开后直接内部连接es,因此我就在windows下装了】


    配置ES允许head插件访问

    修改ES配置文件,允许跨域【直接赋值,冒号后面空格是必要的!,因为这是yml的格式!】:

    http.cors.enabled: true
    http.cors.allow-origin: "*"
    

    集群搭建

    1. 创建多个节点,我以两个节点为例(3个会看的更清晰一些)

      使用3个做测试会看的更清晰一些
      例如:我们创建一个索引,具备5个分片2个副本,那么这3台会散列存储这些数据,任意宕掉一个,不会影响我们的整使用,但是健康会从红色变为黄色
      假如3台数据散列如下

      node1 0 2 3 4
      node2 1 3 4
      node3 0 1 2

      我们手动终止一台,模拟宕机,健康变为黄色

      再终止一台,则健康变为红色!等待一台机器重启后散列会如下(将缺失数据互相获取):

      此时健康是黄色,但是如果node3重启了,则散列又会变为和最初一致

      node1 0 2 3 4
      node2 1 3 4
      node3 0 1 2
    2. 将ES中数据清空(将多个节点中的data删除掉)【/opt/elasticsearch/elasticsearch-7.8.1下 执行 rm -rf data】

    3. 如果内存不足,我们去jvm.options调整下内存限制(如果内存不足设置低一点)

    (在写的时候记得开头要有空格!!)
    # 指定集群
     cluster.name: codenxj # 集群名称
     node.name: nxj1 # 节点名
     network.host: 10.17.4.174 # 绑定的节点1地址
     network.bind_host: 0.0.0.0 # 此项不设置你试试本机可能访问不了啊
     discovery.zen.ping.unicast.hosts: ["10.17.4.174","10.17.4.211"] #TCP端口相互连接hosts列表
     discovery.zen.minimum_master_nodes: 1
    
    
    # 指定集群
    cluster.name: codenxj # 集群名称
    node.name: nxj2 # 节点名
    network.host: 10.17.4.211 # 绑定的节点1地址
    network.bind_host: 0.0.0.0 # 此项不设置你试试本机可能访问不了啊
    discovery.zen.ping.unicast.hosts: ["10.17.4.174","10.17.4.211"] #hosts列表
    discovery.zen.minimum_master_nodes: 1
    
    
    transport.tcp.port: 9300 #这个是与java通讯的端口(默认9300)
    

    配置完成后,一个个启动

    然后打开kibana连接任意一台节点,输入GET _cat/health?v

    如下:

    image-20210323210937742

    成功!

    在head中连接任意一台节点查看(过了一会) 连接,变为绿色的了,集群搭建成功!

  • 相关阅读:
    vue-常用指令汇总
    vue-插槽和具名插槽
    vue-传值校验
    vue-动态组件
    vue-组件
    zend studio 快捷键收集
    php调试工具firephp
    zend studio插件
    MySQL各个版本区别
    PHP 中 Date 函数与实际时间相差8小时的解决方法
  • 原文地址:https://www.cnblogs.com/ningxinjie/p/14563997.html
Copyright © 2011-2022 走看看