简介
Elasticsearch(以下简称 ES)是一个基于 Lucene 的搜索服务器, 它提供了一个分布式多用户能力的全文搜索引擎. 基于 RESTful web 接口. 要想深入了解 ES, 需要先对 Lucene 有一个清晰的认识, 那么什么是 Lucene 呢?
Lucene
普通数据库的缺陷:
没有高效的索引方式, 查询的速度在大量数据的情况下很慢
搜索效果差, 只能对用户输入的完整关键字进行首尾模糊匹配
用户搜索时如果错输, 则查询的结果可能差别很大
搜索引擎
搜索引擎是指根据一定的策略, 运用特定的计算机程序从互联网上搜集信息, 对信息进行组织和处理后, 为用户提供检索服务. 将用户检索相关的信息展示给用户的系统.
分类:
垂直搜索: 通常也叫做细分, 指专门针对某一类信息进行搜索
综合搜索: 是指对众多信息进行综合性的搜索, 如: 百度, 谷歌...
站内搜索: 对网站内部的信息进行搜索, 对自己数据库进行搜索
软件内部搜索: 如 Word / idea 进行搜索
倒排索引技术
倒排索引 (反向索引) 以词条为索引, 表中关键字对应的记录项记录了出现这个字或词的所有文档, 每一个表项记录该文档的 ID 和关键字在该文档中出现的位置情况
全文检索
计算机对文档的全部内容进行分词, 对每个词建立一个索引, 索引记录单词出现的位置和 c
Lucene 是一个开源的全文检索引擎工具包
安装
bin: 脚本目录, 包括: 启动, 停止等可执行脚本
config: 配置文件目录
data: 索引目录, 存放索引文件的地方
logs: 日志目录
modules: 模块目录, 包括了 es 的功能模块
plugins : 插件目录, es 支持插件机制
配置文件
三个配置文件
Elasticsearch.YAML: 用于配置 Elasticsearch 运行参数
jvm.options: 用于配置 Elasticsearch JVM 设置
log4j2.properties: 用于配置 Elasticsearch 日志
es.YAML
- # 常用的配置项如下:
- # 配置 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 插件
下载
Git clone Git://GitHub.com/mobz/Elasticsearch-head.Git cd Elasticsearch-head NPM install NPM run start open
运行
Head 操作 ES
创建索引库
ES 的索引库是一个逻辑概念, 它包括了分词列表及文档列表, 同一个索引库中存储了相同类型的文档. 它就相当于
MySQL 中的表, 或相当于 MongoDB 中的集合
使用 RESTful 风格的方式来创建: 使用 postman 发送如下请求
- put http://localhost:9200 / 索引库名称(相当于创建了 MySQL 中的表)
- {
- "settings":{
- "index":{
- "number_of_shards":1, // 分片数量
- "number_of_replicas":0 // 副本数量
- }
- }
- }
使用 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
可以发现, ES 原始分词器将每个中文字都认为是一个词, 这完全不符合我们的要求, 因此我们需要安装中文分词器
下载 IK
GitHub 地址: https://github.com/medcl/elasticsearch-analysis-ik
安装
解压, 并将解压的文件拷贝到 ES 安装目录的 plugins 下的 ik 目录下
重启 ES 测试
重新发送 HTTP 请求
POST localhost:9200/_analyze
在 JSON 数据中添加参数:
{"text":"中华人民共和国人民大会堂","analyzer":"ik_max_word"}
对于 analyzer 属性, 是 ik 的分词模式. 有两种取值:
ik_max_word : 细粒度分词, 如上面的文档会被分为: 中华人民共和国, 中华, 人民, 共和国, 华人...
ik_smart : 粗粒度分词, 中华人民共和国, 人民大会堂.
自定义词库
对于一些我们网站自己用到的 / 非常见词条. 我们就需要进行自定义词库了, 怎么实现呢?
打开 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>
在 my.dic 文件中, 每一行输入一个词条, 并且保存成 无 BOM UTF-8 格式文件.
重启 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 支持的数值类型有这么多:
在创建数值类型字段时, 有以下几点建议:
尽量选择范围小的类型, 以提高搜索效率
对于浮点数, 尽量使用比例因子. 例如金钱, 设置比例因子为 100, 则 23.45 元会存储为 2345 分. 如果输入的是 23.456 ES 就会将它 * 100 然后四舍五入, 存储成 2346 . 使用比例因子的好处是整型比浮点型更易压缩, 节省磁盘空间
- "price": {
- "type": "scaled_float",
- "scaling_factor": 100
- },
如果比例因子不适合, 则从下表中选择合适的类型
来源: https://www.cnblogs.com/keatsCoder/p/11337196.html