• ElasticSearch入门笔记


    全文检索

    是 一种非结构化数据的搜索方式

    结构化数据一般存入数据库,使用sql语句即可快速查询。但由于非 结构化数据的数据量大且格式不固定,我们需要采用全文检索的方 式进行搜索。全文检索通过建立倒排索引加快搜索效率。

    索引

    将数据中的一部分信息提取出来,重新组织成一定的数据结构,我 们可以根据该结构进行快速搜索,这样的结构称之为索引。 索引即目录,例如字典会将字的拼音提取出来做成目录,通过目录 即可快速找到字的位置。

    索引分为正排索引和倒排索引。

    image-20220924173024281

    
    
    docker run --restart=always  -p 9200:9200  -p 9300:9300  -e "discovery.type=singlenode"  -e ES_JAVA_OPTS="-Xms512m  -Xmx512m"  --name='elasticsearch'  --net elastic  -d  elasticsearch:7.17.0
    
    
    
    
    
    docker run  --name kibana   --net elastic  --link elasticsearch:elasticsearch   -p 5601:5601   -d kibana:7.17.0
    
    
    
    docker run --name kibana --restart=always -e ELASTICSEARCH_URL=http://43.138.222.42:9200 -p 5601:5601 -d kibana:7.8.0
    
    

    Elasticsearch常用操作_文档操作

    创建有结构的索引
    PUT /索引名
    {
        "mappings":{
            "properties":{
                "域名1":{
                    "type":域的类型,
                    "store":是否单独存储,
                    "index":是否创建索引,
           "analyzer":分词器
               },
                "域名2":{
                    ...
               }
            }
       }
    }
    
    如:
    PUT /student1
    {
       "mappings": {
         "properties": {
           "id":{
             "type": "integer"
           },
           "name":{
             "type": "text"
           },
           "age":{
             "type": "integer"
           }
         }
       }
    }
    
    
    删除索引
    DELETE 索引名
    如: DELETE student
    
    1. 新增/修改文档 :id值存在就是修改,不存在就是新增

      注:id值不写时自动生成文档id,id和已有id重复时修改文档

    POST /索引/_doc/[id值]
    {
     "field名":field值
    }
    如:
    POST /student1/_doc/1
    {
      "id":1,
      "name":"tanyang",
      "age":22
    }
    
    1. 根据id查询文档

      GET /索引/_doc/id值
      如:GET student1/_doc/1
      
    2. 删除文档

    DELETE /索引/_doc/id值
    ```

    1. 根据id批量查询文档

      GET /索引/_mget
      {
          "docs":[
             {"_id":id值},
             {"_id":id值}
         ]
      }
      
      
    2. 查询所有文档

      GET /索引/_search
      {
         "query": {
             "match_all": {}
         }
      }
      
    3. 修改文档部分文字字段

      POST /索引/_doc/id值/_update
      {
          "doc":{
              域名:值
       }
      }
      

    Elasticsearch执行删除操作时,ES先标记文档为deleted状态, 而不是直接物理删除。当ES存储空间不足或工作空闲时,才会 执行物理删除操作。 Elasticsearch执行修改操作时,ES不会真的修改Document中 的数据,而是标记ES中原有的文档为deleted状态,再创建一个 新的文档来存储数据。

    Elasticsearch常用操作_域的属性

    PUT /索引名
    {
        "mappings":{
            "properties":{
                "域名1":{
                    "type":域的类型,
                    "store":是否单独存储,
                    "index":是否创建索引,
           "analyzer":分词器
               },
                "域名2":{
                    ...
               }
               }
       }
    }
    
    
    index

    建立倒排索引: 给某个域添加"index":true才能建立倒排索引

    在声明的时候声明域名 添加"index":true

    查询"name":“love” 就能查询 i love you 的文档 这就是倒排索引

    该域是否创建索引。只有值设置为true,才能根据该域的关键词查 询文档。

    // 根据关键词查询文档
    GET /索引名/_search
    {
    		 "query":{
            "term":{
               搜索字段: 关键字
                   }
               }
    }
    
    
    store

    image-20220925005541370

    是否单独存储。如果设置为true,则该域能够单独查询。

    // 单独查询某个域:
    GET /索引名/_search
    {
      "stored_fields": ["域名"]
    }
    

    分词器

    standard analyzer:Elasticsearch默认分词器,根据空格和标点 符号对英文进行分词,会进行单词的大小写转换。

    默认分词器是英文分词器,对中文的分词是一字一词。

    语法:
     GET /_analyze
    {
     "text":测试语句,
     "analyzer":分词器
    }
    
    使用:
    GET /_analyze
    {
       "text":"I love Spring",
        "analyzer": "standard"
    }
    查询结果:
    {
      "tokens" : [
        {
          "token" : "i",
          "start_offset" : 0,
          "end_offset" : 1,
          "type" : "",
          "position" : 0
        },
        {
          "token" : "love",
          "start_offset" : 2,
          "end_offset" : 6,
          "type" : "",
          "position" : 1
        },
        {
          "token" : "spring",
          "start_offset" : 7,
          "end_offset" : 13,
          "type" : "",
          "position" : 2
        }
      ]
    }
    
    

    IK分词器

    IKAnalyzer是一个开源的,基于java语言开发的轻量级的中文分词 工具包。提供了两种分词算法:

    • ik_smart:最少切分

    • ik_max_word:最细粒度划分

    测试分词器效果
    GET /_analyze
    {
     "text":"测试语句",
     "analyzer":"ik_smart/ik_max_word"
    }
    
    IK分词器词典

    IK分词器根据词典进行分词,词典文件在IK分词器的config目录中。 main.dic:IK中内置的词典。记录了IK统计的所有中文单词。 + IKAnalyzer.cfg.xml:用于配置自定义词库。

    <properties>
            <comment>IK Analyzer 扩展配置
    comment>
            <!--用户可以在这里配置自己的扩展字典 --
    >
            <entry
    key="ext_dict">ext_dict.dicentry>
             
            <entry
    key="ext_stopwords">ext_stopwords.dicent
    ry>
            
            
            
            
    properties>
    

    拼音分词器

    将拼音分词器安装到es的plugins目录后重启

    拼音分词器只能粉刺所有字的首字母拼音和每个字的拼音 不能分成词组拼音。

    测试分词效果

    GET /_analyze
    {
     "text":测试语句,
     "analyzer":pinyin
    }
    

    自定义分词器

    自定义分词器配置

    image-20220925100504523

    PUT /索引名
    {
        "settings" : {
            "analysis" : {
                "analyzer" : {
                    "ik_pinyin" : { //自定义分词器名
                      "tokenizer":"ik_max_word", // 基本分词器
                        "filter":"pinyin_filter"
    // 配置分词器过滤
                   }
               },
                "filter" : { // 分词器过滤时配置另一
    个分词器,相当于同时使用两个分词器
                   "pinyin_filter" : {
                       "type" : "pinyin", // 另一
    个分词器
                       // 拼音分词器的配置
                      
    "keep_separate_first_letter" : false, // 是否
    分词每个字的首字母
                       "keep_full_pinyin" :
    true, // 是否分词全拼
                       "keep_original" : true,
    // 是否保留原始输入
                       "remove_duplicated_term"
    : true // 是否删除重复项
                   }
               }
           }
       },
        "mappings":{
            "properties":{
                "域名1":{
                    "type":域的类型,
                    "store":是否单独存储,
                    "index":是否创建索引,
           "analyzer":分词器
               },
                "域名2":{
    
    测试自定义分词器
    GET /索引/_analyze
    {
      "text": "你好百战程序员",
      "analyzer": "i love spring"
    }
    
    1.查询students索引下的全部文档 
    GET /students/_search
    {
       "query":{
         "match_all": {} 
       }  
    }
    
    
    2.match:全文检索。将查询条件分词后再进行搜索。
    条件查询 查询students索引下的info "JAVA很好的会进行分词查询"
    GET /students/_search
    {
       "query": {
         "match": {
           "info": "Java很好的"
         }
       }
    }
    

    注:在搜索时关键词有可能会输入错误,ES搜索提供了自动 纠错功能,即ES的模糊查询。使用match方式可以实现模糊 查询。模糊查询对中文的支持效果一般,我们使用英文数据 测试模糊查询。

    GET /students/_search
    {
       "query": {
         "match": {
           "info":{
             "query":"love",
            "fuzziness":2
         }
       }
      }
    }
    
    range:范围搜索。对数字类型的字段进行范围搜索
    {
     "query":{
            "range":{
                搜索字段:{
                    "gte":最小值,
                    "lte":最大值
               }
           }
       }
    }
    gt/lt:大于/小于
    gte/lte:大于等于/小于等于
    
    match_phrase:

    短语检索。搜索条件不做任何分词解析,在搜 索字段对应的倒排索引中精确匹配。

    {
     "query":{
            "match_phrase":{
                搜索字段:搜索条件
           }
       }
    }
    
    term/terms:

    单词/词组搜索。搜索条件不做任何分词解析,在 搜索字段对应的倒排索引中精确匹配

    {
     "query":{
            "term":{  
     搜索字段: 搜索条件
           }
       }
    }
    {
     "query":{
            "terms":{  
     搜索字段: [搜索条件1,搜索条件2]
           }
       }
    }
    

    Elasticsearch搜索文档_复合搜索

    GET /索引/_search
    {"query": {
            "bool": {
                // 必须满足的条件
                "must": [
     搜索方式:搜索参数,
     搜索方式:搜索参数
               ],
                // 多个条件有任意一个满足即可
                "should": [
     搜索方式:搜索参数,
       搜索方式:搜索参数
       ],
     // 必须不满足的条件
       "must_not":[
       搜索方式:搜索参数,
       搜索方式:搜索参数
       ]
       }
       }
    }
    

    Elasticsearch搜索文档_结果排序

    ES中默认使用相关度分数实现排序,可以通过搜索语法定制化排 序。

    默认是按照相关度排序的 _source

    GET /索引/_search
    {
        "query": 搜索条件,
        "sort": [
       {
       "字段1":{
       "order":"asc"
           }
       },
       {
       "字段2":{
       "order":"desc"
       					}
            }
       		]
    }
    

    Elasticsearch搜索文档_分页查询

    GET /索引/_search
    {
     "query": 搜索条件,
     "from": 起始下标,
     "size": 查询记录数
    }
    
    
    

    Elasticsearch搜索文档_高亮查询

    我们可以在关键字左右加入标签字符串,数据传入前端即可完成高 亮显示,ES可以对查询出的内容中关键字部分进行标签和样式的设 置。

    GET /索引/_search
    {
     "query":搜索条件,
     "highlight":{
     "fields": {
           "高亮显示的字段名": {
                    // 返回高亮数据的最大长度
           "fragment_size":100,
     // 返回结果最多可以包含几段不连续
    的文字
           "number_of_fragments":5
           }
           },
            "pre_tags":["前缀"],
            "post_tags":["后缀"]
       }
    }
    
    

    实战

    @Document(indexName = "product",createIndex
    = true)
    @Data
    public class Product {
        @Id
        @Field(type = FieldType.Integer,store =
    true,index = true)
        private Integer id;
        @Field(type = FieldType.Text,store =
    true,index = true,analyzer =
    "ik_max_word",searchAnalyzer =
    "ik_max_word")
        private String productName;
        @Field(type = FieldType.Text,store =
    true,index = true,analyzer =
    "ik_max_word",searchAnalyzer =
    "ik_max_word")
        private String productDesc;
    }
    

    @Document:标记在类上,标记实体类为文档对象,一般有如 下属性: indexName:对应索引的名称 createIndex:是否自动创建索引

    @Id:标记在成员变量上,标记一个字段为主键,该字段的值会 同步到ES该文档的id值。

    @Field:标记在成员变量上,标记为文档中的域,一般有如下 属性: type:域的类型 index:是否创建索引,默认是 true store:是否单独存储,默认是 false analyzer:分词器 searchAnalyzer:搜索时的分词器

  • 相关阅读:
    【Stable Diffusion】入门-02:AI绘画提示词+参数设置攻略
    raft加速日志回退算法以及理解的基础_一些举例
    照片转换成3D软件有什么?建议收藏这些软件
    C++(11):to_string及stoi
    脚本语言Lua的基础知识总结
    m基于GA遗传优化的BP神经网络时间序列预测算法matlab仿真
    【Linux】线程池
    wpf-窗口设计-常用小技巧
    vue3中引入全局的less 和配置代理
    Linux系统调优详解(十二)——IO调优之磁盘测速
  • 原文地址:https://blog.csdn.net/qq_50629351/article/details/127039295