ElasticSearch安装使用

简介:

  • 全文搜索属于最常见的需求,开源的Elasticserch是目前全文搜索引擎的首选.
  • 它可以快速地储存,搜索,和分析海量数据.维基百科,Stack OverFlow,github,都采用它
  • Elastic底层是开源库,Lucene,但是,你没法直接用Lucene,必须自己写代码去调用它的接口,Elastic是Lucene的封装,提供了REST API 的操作接口,开箱即用. 官网参考文档

一,基本概念

1. Index(索引)

  • 动词,相当于mysql中的insert操作(索引一条数据)
  • 名词,相当于mysql中的Database

2. Type(类型)

  • 在Index(索引)中,可以定义一个或多个类型

  • 类似于mysql中的table,每一种类型的数据放在一起

3. Document(文档)

  • 保存在某个索引(Index)下的,某种类型(Type)的一个数据(Document),文档是JSON格式的,Document就像是mysql中的某个Table里面的内容.

二,Docker安装ES

  • elasticsearch:

    • docker run --name elasticsearch -p 9200:9200 -p 9300:9300
      -e “discovery.type=single-node”
      -e ES_JAVA_OPTS="-Xms64m -Xmx128m"
      -v /dockerData/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml
      -v /dockerData/elasticsearch/data:/usr/share/elasticsearch/data
      -v /dockerData/elasticsearch/plugins:/usr/share/elasticsearch/plugins
      -d elasticsearch:7.8.0

    • discovery.type=single-node:单节点启动

    • ES_JAVA_OPTS="-Xms64m -Xmx128m:初始64M,elasticsearch最大占用128M

  • kibana(图形化操作elasticsearch,不装也行,原理是发请求,postman可以代替):

    • docker run --name kibana -e ELASTICSEARCH_HOSTS=http://39.100.66.142:9200 -p 5601:5601 -d kibana:7.8.0

    • ELASTICSEARCH_HOSTS:配置es的地址

三, 初步检索

1. _cat

  • GET /_cat/nodes : 查看所有节点
  • GET /_cat/health : 查看es健康状态
  • GET /_cat/master : 查看主节点
  • GET /_cat/indices :查看所有索引 类似 show databases

2. 索引一个文档(保存)

  • 保存一个数据,保存在哪个索引的哪个类型下,指定用哪一个唯一标识
  • PUT /customer/external/1 body: {“name”:“特朗普nb”} 在customer索引下的external类型下保存1号数据
  • 其实PUT和POST都可以实现保存,区别:
    • POST新增/修改,如果不指定id,会自动生成id 做新增操作,如果指定id并且指定的id已经存在,那么就会做修改操作,并增加版本号
    • PUT新增/修改,PUT必须指定id,不指定id会报错,所以一般用PUT做修改操作

3. 查询文档

  • GET /customer/external/1

  • 结果:

    {
          "_index": "customer", //索引
          "_type": "external", //分类
          "_id": "1", //id
          "_version": 1, //版本
          "_seq_no": 0, //并发控制字段,每次更新就会+1,用来做乐观锁
          "_primary_term": 1, //同上,主分片重新分配,如果重启,就会发生变化
          "found": true,
          "_source": { //真正的内容
            "name": "特朗普nb"
          }
        }
        //乐观锁修改实现,更新携带 ?if_seq_no=0&if_primary_term=1 ,只想对_seq_no值为0,_primary_term为1的数据进行修改,如果在这之前有人修改了原数据,使这两个值发生改变,那么我将不继续修改抱409错误 
    

4. 更新文档

  • POST customer/external/1/_update body:{“doc”:{“name”:“特朗普lj”}} 如果带上_update body中就要带上doc

  • POST customer/external/1 body:{“name”:“特朗普lj”}

  • PUT

  • 区别:

    • post带update : 会对比原来的数据,如果与原来一样,就什么都不做,version,seq_no都不变
    • put和post(不带update):直接更新

5. 删除文档&索引

  • DELETE /customer/external/1
  • DELETE /customer
  • 没有删除类型的操作

6.bulk批量API

  • POST customer/external/_bulk

    • body:

    • {“index”:{"_id":“1”}}

      {“name”:“华盛顿”}

      {“index”:{"_id":“2”}}

      {“name”:“雷克顿”}

    • 语法格式:

    • 两行为一组 删除操作单独一行

      {action:{metadata}

      {request body}

      action: 需要执行什么操作 index 保存操作

      metadata: 原数据信息 哪个索引,哪个分类,哪个id 等等

      request body 真正的请求体

    • 复杂实例:

    • 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 Update Blog Post”}}

    • 官网提供的批量数据

四,进阶检索

1. Search API

  • ES支持两种基本方式检索:

    • 一个是通过REST request URI 发送搜索参数(uri+检索参数)
    • 另一个是通过 REST request body 来发送参数(uri+请求体)
  • 检索信息

    • 一切检索从_search开始

    • uri+检索参数进行检索

      • GET bank/_search 检索bank下所有信息,包括type和docs
      • GET bank/_search?q=*&sort=account_number:asc 请求参数方式检索(*查询所有,按照account_number字段升序)
    • uri+请求体进行检索(用postman get不能携带body,用post也可以检索)

      • GET bank/_search

      • //请求体遵循Query DSL语法规则
        {
            "query":{
                "match_all":{}
            },
            "sort":[{
                "account_number":"asc"
            }]
        }
        
    • 响应结果:

      • took :执行检索的耗时(毫秒)
      • time_out : 是否超时
      • _shards : 分片信息(搜索了多少个分片,以及成功,失败或跳过了多少个分片)
      • max_score : 找到的最相关文件的分数
      • hits.total.value : 找到了多少个匹配的文档
      • hits.sort : 文档的排序位置(不按相关性得分排序时)
      • hits._score : 文档的相关性得分(使用时不适用match_all

2. Query DSL

(1). 基本语法格式
  • ES提供了一个可以执行查询的json风格DSL(domain-specific language 领域特定语言).这个被称为 Query DSL.该查询语言非常全面.

  • 典型结构:

    • {

      ​ QUERY_NAME : {

      ​ ARGUMENT : VALUE,

      ​ ARGUMENT : VALUE…

      ​ },

      ​ QUERY_NAME : {

      ​ ARGUMENT : VALUE,

      ​ ARGUMENT : VALUE…

      ​ }…

      }

  • 针对某个字段:

    • {

      ​ QUERY_NAME : {

      ​ FIELD_NAME:{

      ​ ARGUMENT : VALUE,

      ​ ARGUMENT : VALUE…

      ​ }

      ​ }

      }

(2). 返回部分字段
  • {

    ​ QUERY_NAME : {

    ​ ARGUMENT : VALUE,

    ​ ARGUMENT : VALUE…

    ​ },

    ​ “from”:0,

    ​ “size”: 5,

    ​ “_source”:[“age”,“balance”]

    }

    //从第0个开始,返回5条,只返回age和balance字段

(3). match 匹配查询
  • 基本类型(非字符串),精准匹配(字段.keyword也能做精准匹配)

    • {
          "query":{
              "match":{
                  "account_number":20
              }
          }
      }
      //匹配account_number=20的数据 
      
  • 字符串 全文检索

    • {
        "query": { 
          "match": {
            "address": "Perry"
          }
        }
      }
      //匹配address中包含Perry的所有数据
      
      {
        "query": { 
          "match": {
            "address": "Perry Argyle"
          }
        }
      }
      //并且根据空格进行分词  匹配adress中包含Perry或者Argyle或者Perry Argyle的所有数据
      
(4). match_phrase 短语匹配
  • 将匹配值当成一个整体(不分词)进行检索

    • {
        "query": { 
          "match_phrase": {
            "address": "Perry Argyle"
          }
        }
      }
      //匹配adress中包含Perry Argyle的数据
      
(5). multi_match 多字段匹配
  • 多个字段匹配指定值,会分词

    • {
        "query": { 
          "multi_match": {
            "query": "mill Tibbie",
            "fields": ["address","city"]
          }
        }
      }
      //匹配address或者city中包含mill或Tibbie或mill Tibbie的所有数据
      
(6). bool 复合查询
  • bool用来做复合查询,复合查询可以合并任何其他查询语句,包括复合查询,可以嵌套

    • {
        "query": {
          "bool": {
            "must": [
              {"match": {
                "gender": "M"
              }},{
                "match": {
                  "address": "mill"
                }
              }
            ],
            "must_not": [
              {"match": {
                "age": 28
              }}
            ]
          }
        }
      }
      //must 必须同时满足 相当于and 必须同时满足gender和address
      //must_not 必须同时不满足  must_not会被当成一个filter不会参与计算相关性得分
      //should 期望 不一定要满足 当然,满足条件可以加分
      
(7). filter 结果过滤
  • 并不是所有查询都会产生分数,特别是那些进用于过滤的文档,为了不计算分数,es会自动检查场景并且优化查询的执行
(8). term
  • 和match功能类似,所以一般 全文检索字段用match,其他非text字段用term
(9). aggregations(执行聚合)

五. Mapping

1. mapping

  • mapping映射,是用来定义文档及其包含的字段的存储和索引方式的过程,例如

  • 哪些字符串应该视为全文字段

  • 哪些字段包含数字,日期或者地理位置

  • 日期值的格式

  • 自定义规则,用于控制动态添加字段的映射

2. 字段数据类型

  • 每个字段都有一个数据type,如果没有指定,es会进行猜测,字段类型可以是:
    • 简单类型 text,keyword,date,long,double,boolean或ip
    • 支持JSON的分层性质类型,如 object和nested
    • 或一种特殊类型 如geo_point,geo_shape或completion

3. mapping操作

  • 在es7.0以后就已经不再推荐type,即由 index-type-document变为 index-document,无type的默认type为_doc
(1). 创建映射
  • //PUT /my_index
    {
        "mappings":{
            "properties":{
                "age":{"type":"integer"},
                "email":{"type":"keyword"},
                "mame":{"type":"text"}
            }
        }
    }
    //GET /my_index/_mapping 可以查看索引的映射
    
(2). 添加新的字段
  • //PUT /my_index/_mapping
    {
        "properties":{
            "employee_id":{
                "type":"keyword",
                "index":false
            }
        }
    }
    //index 字段是否参与检索,默认为true
    
(3). 更新映射
  • 对于已经存在的映射字段,es不支持更新,如果想要实现更新,就必须创建新的索引,然后进行数据迁移
(4). 数据迁移
  • //POST _reindex 固定写法
    {
      "source": {
        "index": "bank",
        "type": "account"
      },
      "dest": {
        "index": "newbank"
      }
    }
    //把bank索引下类型为account的文档迁移(复制)到 newbank下(有type迁移到无type)
    
(5). 分词
  • 一个tokenizer(分词器)接收一个字符流,将之分割为独立的tokens(词元,通常是独立的单词),然后输出tokens流.例如 whitespace tokenizer遇到空白字符时分割文本,它会将文本"Quick fox jumps"分割为[“Quick”,“fox”,“jumps”],该tokenizer(分词器)还负责记录各个term(词条)的顺序或position(位置)(用于phrase短语和word proximity词邻近查询),以及term所代表的原始word(单词)的start(起始)和end(结束)的character offsets(字符偏移量)(用于高亮显示搜索内容),es提供了很多内置分词器,可以用来构建custom analyzers(自定义分词器)
ik分词器
  • 安装: 在github上下载和es对应版本ik的zip文件,解压到es的plugins文件夹下即可

  • 测试

    • //GET _analyze
      {
        "analyzer": "ik_smart",
        "text": "美国新增确诊再创新高"
      }
      //[美国,新增,确诊,再创新高]
      {
        "analyzer": "ik_max_word",
        "text": "美国新增确诊再创新高"
      }
      //[美国,新增,确诊,再创新高,再创,创新高,创新,新高] 最全匹配
      
  • 自定义词库

    • 修改es的config/IKAnalyzer.cfg.xml文件,导入自定义词库(可以用本地文件,也可以使用nginx导入远程词库)
    • 在这里插入图片描述

六. Elasticsearch-Rest-Client

  • 9300端口(tcp)
    • spring-data-elasticsearch:transport-api.jar
      • springboot版本不同,transport-api.jar不同,不能适配es版本
      • 7.x已经不建议使用,预期8.x废弃
  • 9200端口(http)
    • JestClient 非官方,更新慢
    • RestTemplate,HttpClient 模拟发送http请求,ES很多操作需要自己封装,麻烦
    • Elasticsearch-Rest_Client 官方RestClient,封装了ES操作,API层次分明,易上手(最终选择)
  • es程序操作API
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

climb.xu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值