• ElasticSearch基础知识


    简介

    ElasticSearch(以下简称ES)是一个基于Lucene的搜索服务器,它提供了一个分布式多用户能力的全文搜索引擎。基于RESTful web接口。要想深入了解 ES,需要先对 Lucene 有一个清晰的认识,那么什么是 Lucene 呢?

    Lucene

    普通数据库的缺陷:

    • 没有高效的索引方式,查询的速度在大量数据的情况下很慢
    • 搜索效果差,只能对用户输入的完整关键字进行首尾模糊匹配
    • 用户搜索时如果错输,则查询的结果可能差别很大

    搜索引擎

    搜索引擎是指根据一定的策略,运用特定的计算机程序从互联网上搜集信息,对信息进行组织和处理后,为用户提供检索服务。将用户检索相关的信息展示给用户的系统。

    分类:

    垂直搜索:通常也叫做细分,指专门针对某一类信息进行搜索

    综合搜索:是指对众多信息进行综合性的搜索,如:百度、谷歌。。。

    站内搜索:对网站内部的信息进行搜索,对自己数据库进行搜索

    软件内部搜索:如 word / idea 进行搜索

    倒排索引技术

    倒排索引(反向索引)以词条为索引,表中关键字对应的记录项记录了出现这个字或词的所有文档,每一个表项记录该文档的ID和关键字在该文档中出现的位置情况

    全文检索

    计算机对文档的全部内容进行分词,对每个词建立一个索引,索引记录单词出现的位置和c

    Lucene 是一个开源的全文检索引擎工具包

    安装

    1565264074745

    bin:脚本目录,包括:启动、停止等可执行脚本
    config:配置文件目录
    data:索引目录,存放索引文件的地方
    logs:日志目录
    modules:模块目录,包括了es的功能模块
    plugins :插件目录,es支持插件机制

    配置文件

    三个配置文件

    elasticsearch.yml:用于配置Elasticsearch运行参数

    jvm.options:用于配置Elasticsearch JVM设置

    log4j2.properties:用于配置Elasticsearch日志

    es.yml

    # 常用的配置项如下:
    # 配置elasticsearch的集群名称,默认是elasticsearch。建议修改成一个有意义的名称。
    cluster.name: YunShangXue
    # 节点名称
    node.name: masterNode
    # 网络地址,配置成 0.0.0.0 代表任意地址
    network.host: 0.0.0.0:
    # HTTP端口号
    http.port: 9200
    # 集群交互的端口号
    transport.tcp.port: 9300
    # 指定该节点是否有资格被选举成为master结点,如果原来的master宕机会重新选举新的master
    node.master: true
    # 是否是数据节点
    node.data: true
    # 开发环境下集群节点的地址和端口们
    discovery.zen.ping.unicast.hosts: ["0.0.0.0:9300", "0.0.0.0:9301", "0.0.0.0:9302"]
    # 主结点数量的最少值 ,此值的公式为:(master_eligible_nodes / 2) + 1 ,比如:有3个符合要求的主结点,那么这里要设置为2。
    discovery.zen.minimum_master_nodes: 1
    # 锁住ES使用的内存,避免内存与swap分区交换数据。
    bootstrap.memory_lock: false
    # 单机允许的最大存储结点数,通常单机启动一个结点建议设置为1,开发环境如果单机启动多个节点可设置大于1
    node.max_local_storage_nodes: 1
    # 索引文件、日志文件路径
    path.data: D:ElasticSearchelasticsearch‐6.2.1data
    path.logs: D:ElasticSearchelasticsearch‐6.2.1logs
    # 允许跨域?
    http.cors.enabled: true
    http.cors.allow‐origin: /.*/
    # 设置ES自动发现节点连接超时的时间,默认为3秒,如果网络延迟高可设置大些。
    discovery.zen.ping.timeout: 3s 
    

    jvm.options

    设置最小及最大的JVM堆内存大小:
    在jvm.options中设置 -Xms和-Xmx:

    • 两个值设置为相等
    • 将 Xmx 设置为不超过物理内存的一半。

    log4j2.properties

    日志文件设置,ES使用log4j,注意日志级别的配置。生产环境下设置为 error

    安装 head 插件

    1. 下载
    git clone git://github.com/mobz/elasticsearch-head.git cd elasticsearch-head npm install npm run start open
    
    1. 运行

    1565267333102

    Head操作ES

    创建索引库

    ES的索引库是一个逻辑概念,它包括了分词列表及文档列表,同一个索引库中存储了相同类型的文档。它就相当于
    MySQL中的表,或相当于Mongodb中的集合

    1. 使用 RESTful 风格的方式来创建:使用 postman 发送如下请求
    put http://localhost:9200/索引库名称(相当于创建了MySQL中的表)
    
    {
      "settings":{
      "index":{
          "number_of_shards":1, // 分片数量
          "number_of_replicas":0 // 副本数量
       }    
      }
    }
    

    1565268120655

    1. 使用 Head 插件直接创建

    创建映射

    概念说明

    MySQL ES
    数据库
    索引库(6.0以后淡化了 Type 的概念,9.0将会取缔)
    字段 字段
    行记录 文档

    创建映射就是指定文档中包括的字段

    PUT http://localhost:9200/索引库名称/类型名称/_mapping
    

    这里我们使用的 ES 版本是 6.2.1 虽然已经弱化 Type 的概念,但是并没有完全删除,所以我们可以起一个没有任何意义的名称作为 Type

    {
        "properties": { 
            "name": {
                "type": "text"
            },
            "description": {
                "type": "text"
            },
            "studymodel": {
                "type": "keyword"
            }
        }
    }
    

    如果想查询映射,将 put 请求切换成 get 请求即可

    添加文档

    请求格式:

    POST http://localhost:9200/索引名/类型名/id值
    

    如果不指定 id 值 ES 会自动生成 ID

    {
      "name":"Bootstrap开发框架",
      "description":"Bootstrap是由Twitter推出的一个前台页面开发框架,在行业之中使用较为广泛。此开发框架包含了大量的CSS、JS程序代码,可以帮助开发者(尤其是不擅长页面开发的程序人员)轻松的实现一个不受浏览器限制的精美界面效果。",
      "studymodel":"201001"
    }
    

    搜索文档

    根据ID查询文档:

    GET http://localhost:9200/ysx_course/doc/gf7ic2wBmvkgEzxNIJl0
    

    查询全部文档

    GET http://localhost:9200/ysx_course/doc/_search
    

    根据 name 字段查询。查询的结果匹配度越高越靠前

    GET http://localhost:9200/ysx_course/doc/_search?q=name:XXX
    http://localhost:9200/ysx_course/doc/_search?q=name:Spring
    

    查询到的结果

    {
        "took": 3, // 本次操作花费的时间/ms
        "timed_out": false, // 请求是否超时
        "_shards": {
            "total": 1, // 查询到的结果数
            "successful": 1, 
            "skipped": 0,
            "failed": 0
        },
        "hits": {
            "total": 1, // 符合条件的文档总数
            "max_score": 0.9530774, // 文档匹配得分,这里为最高分
            "hits": [ // 匹配度较高的前N个文档
                {
                    "_index": "ysx_course",
                    "_type": "doc",
                    "_id": "gf7ic2wBmvkgEzxNIJl0",
                    "_score": 0.9530774, // 每个文档都有一个匹配度得分,按照降序排列
                    "_source": { // 显示了文档的原始内容
                        "name": "Spring",
                        "description": "...",
                        "studymodel": "201001"
                    }
                }
            ]
        }
    }
    

    IK 分词器

    因为 ES 是老外开发的,对中文的支持非常鸡肋,例如:发送请求测试原始分词效果

    POST localhost:9200/_analyze
    

    1565313039330

    可以发现,ES 原始分词器将每个中文字都认为是一个词,这完全不符合我们的要求,因此我们需要安装中文分词器

    下载IK

    GITHUB 地址:https://github.com/medcl/elasticsearch-analysis-ik

    安装

    解压,并将解压的文件拷贝到ES安装目录的plugins下的ik目录下

    1565313211875

    重启ES测试

    重新发送 HTTP 请求

    POST localhost:9200/_analyze
    

    在 JSON 数据中添加参数:

    {"text":"中华人民共和国人民大会堂","analyzer":"ik_max_word"}
    

    对于 analyzer 属性,是 ik 的分词模式。有两种取值:

    • ik_max_word : 细粒度分词,如上面的文档会被分为: 中华人民共和国、中华、人民、共和国、华人...
    • ik_smart : 粗粒度分词,中华人民共和国、人民大会堂。

    自定义词库

    对于一些我们网站自己用到的/非常见词条。我们就需要进行自定义词库了,怎么实现呢?

    1. 打开 ik 文件夹下 config 目录,IKAnalyzer.cfg.xml 文件。可以清楚的看出这个文件中可以配置自定义词库。这里我们在同级目录下创建 my.dic 文件
    <?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">my.dic</entry>
    	 <!--用户可以在这里配置自己的扩展停止词字典-->
    	<entry key="ext_stopwords"></entry>
    	<!--用户可以在这里配置远程扩展字典 -->
    	<!-- <entry key="remote_ext_dict">words_location</entry> -->
    	<!--用户可以在这里配置远程扩展停止词字典-->
    	<!-- <entry key="remote_ext_stopwords">words_location</entry> -->
    </properties>
    
    
    1. 在 my.dic 文件中,每一行输入一个词条,并且保存成 无BOM UTF-8 格式文件。
    2. 重启 ES,进行测试

    映射维护

    说明

    ES 支持映射的新增,但不支持已有字段的更新,如果非要进行更新,就需要删除索引库然后建立新的索引库。。。

    常用映射类型

    字符串: text

    analyzer:属性指定分词器,下边指定name的字段类型为text,使用ik分词器的ik_max_word分词模式

    "name": {
         "type": "text",
         "analyzer":"ik_max_word"
    }
    

    上边指定了analyzer是指在索引和搜索都使用ik_max_word,如果单独想定义搜索时使用的分词器则可以通过
    search_analyzer属性.对于ik分词器建议是索引时使用 ik_max_word 将搜索内容进行细粒度分词,搜索时使用 ik_smart 提高搜索精确性。最终的 JSON 数据如下:

    "name": {
        "type": "text",
        "analyzer":"ik_max_word",
        "search_analyzer":"ik_smart"
    }
    

    index:该属性指定是否索引。默认是 true ,但是对于一些不用于搜索的字段,如图片 url ,就可以设置为 false

    store:是否在source之外存储,每个文档索引后会在 ES中保存一份原始文档,存放在"_source"中,一般情况下不需要设置store为true,因为在_source中已经有一份原始文档了

    字符串: keyword

    keyword 定义的字段表示关键字搜索,是进行整体的搜索,在创建keyword时索引是不进行分词的,比如:邮编、身份证号、手机号等。keyword 字段通常用于过滤、排序、聚合等

    日期: date

    日期类型不用设置分词器。通常日期类型的字段用于排序。

    format:通过format设置日期格式

    {
    "properties": {    
            "timestamp": {
              "type":   "date",
              "format": "yyyy‐MM‐dd HH:mm:ss||yyyy‐MM‐dd" // 日期格式化
            }
          }
    }
    

    数值类型

    ES 支持的数值类型有这么多:

    1565317208924

    在创建数值类型字段时,有以下几点建议:

    1. 尽量选择范围小的类型,以提高搜索效率
    2. 对于浮点数,尽量使用比例因子。例如金钱,设置比例因子为100,则 23.45 元会存储为 2345 分。如果输入的是 23.456 ES就会将它 * 100 然后四舍五入,存储成 2346 .使用比例因子的好处是整型比浮点型更易压缩,节省磁盘空间
    "price": {
      "type": "scaled_float",       
            "scaling_factor": 100
      },
    
    1. 如果比例因子不适合,则从下表中选择合适的类型

    1565317360545

  • 相关阅读:
    工作
    失败
    理想和一些未来的计划
    安静
    重新开始
    如何度过周末
    放假
    WPF学习笔记-数据采集与监控项目01-登录界面
    VS2017-断点感叹号问题,调试代码显示“当前无法命中断点,还没有为该文档加载任何符号”
    WPF-MVVM模式-表现层的UI框架【学习笔记】
  • 原文地址:https://www.cnblogs.com/keatsCoder/p/11337196.html
Copyright © 2020-2023  润新知