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:\ElasticSearch\elasticsearch‐6.2.1\data
path.logs: D:\ElasticSearch\elasticsearch‐6.2.1\logs
# 允许跨域?
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

posted @ 2019-08-11 23:02  后青春期的Keats  阅读(618)  评论(2编辑  收藏  举报