Elasticearch 搜索引擎
简介:
- Elasticsearch是一个基于Lucene的搜索服务器。
Lucene 还是一个库,必须要懂一点搜索引擎原理的人才能用的好,所以后来又有人基于 Lucene 进行封装,写出了 Elasticsearch。
它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。
- Elasticsearch是用 Java语言开发的,并作为
Apache许可条款下的开放源码发布
,是一种流行的企业级搜索引擎。 - 安装简单
开箱即用!
使用时直接解压即可,可以实时与数据库进行更新! Elasticsearch用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。 - 使用简单,内部集成了很多的 http请求,
启动后直接调用即可实现功能。
且支持大量的语言:Java
C#
php
python
… - 官方网址
- Git hub
总结: elasticsearch是一个基于Lucene的高扩展的分布式搜索服务器,支持开箱即用。 elasticsearch隐藏了Lucene的复杂性,对外提供Restful 接口来操作索引、搜索。 突出优点:
- 扩展性好,可部署上百台服务器集群,处理PB级数据。
大数据Byte、KB、MB、GB、TB、PB、EB、ZB、YB、DB、NB
- 近实时的去索引数据、搜索数据。
更新实时数据处理很快,至少比 solr搜索引擎快!
- 可通过自定义插件,如 COS 备份、QQ分词、ik分词器…等满足特定功能需求。
结构 / 原理 :
elasticsearch 的原理就很像是一个数据库 搜索引擎
- 可以存储数据,分析数据,查询…
- elasticaSearch 对于查询效率,存储数据,集群都是优于数据库的,
但它没有数据库的强大 sql能力:
存储过程….
索引结构
- ElasticaSearch中,有几个专业的名词:
索引
类型
文档
ElasticaSearch中的索引,索引与数据库的索引概念不同,它更像是数据库的库
ElasticaSearch中,索引有两种解释:物理概念
黑色,逻辑概念
橙色
物理概念: 索引文件 ElasticSearch 的数据存储文件 , 相当于数据库的 sql 文件! 逻辑概念:
- index索引: 是一个
倒排索引表
- 分词列表:
将Docment 数据,进行倒排索引产生,不重复的组成分词列表。
相当于一个搜索的关键词列表…
百度搜索并不是 模糊查询 而是
关键字查询: 当你百度搜素: 为什么经常掉头发?,并不会针对是根据这个问题给你进行查找,而是可是能:掉发… 经常掉发等关键词… - Document 文档: 每一个 docment相当于一条数据,一个文档里面有 field1 相当于一个个的属性…
Document 使用 JSON 格式表示
为了便于大家理解ES里的数据模型,将它与关系型数据库 MySQL 做类比:
关系数据库 ⇒ 数据库 ⇒ 表 ⇒ 行 ⇒ 列(Columns) Elasticsearch ⇒ 索引(Index) ⇒ 类型(type
7.0即将淘汰
) ⇒ 文档(Docments) ⇒ 字段(Fields)
- 一个 Elasticsearch 集群可以包含多个索引(数据库),也就是说其中包含了很多类型(表)。
6.0及之后移除了一个索引允许映射多个类型的操作,
索引就有点像一个表了… - 这些类型中包含了很多的文档(行),然后每个文档中又包含了很多的字段(列)。
- Elasticsearch的交互,可以使用Java API,也可以直接使用HTTP的Restful API方式
原理:
- ElasticSearch 创建一个index索引
库/表
(版本不同概念会有变化),创建Docment文档一条记录
每次在给文档添加Docment, 都会将数据进行 倒排索引 对文档其中的关键字,生成并生成/存储: 分词列表 - 比如:
百度搜索一个问题: 云顶S1最强阵容组合 装备合成 会根据分词器处理:
云顶
S1
装备
阵容...
等关键词。 之后就会去根据每个 Document 的分词列表进行匹配…匹配度高的就优先展示给用户查看咯~
倒排索引
倒排索引(Inverted Index):倒排索引,它也是索引。索引,初衷都是为了快速检索到你要的数据。
- 倒排索引是实现“单词-文档矩阵”的一种具体存储形式,通过倒排索引, 可以根据单词快速获取包含这个单词的文档列表。倒排索引主要由两个部分组成:“单词词典”和“倒排文件”。
- 书本的目录, 和新华字典的 拼音搜词
目录和索引页,其实就很形象的可以比喻为
正排索引
和倒排索引
。为了进一步加深理解,再看看熟悉的搜索引擎。 - 没有搜索引擎时,我们只能直接输入一个网址,然后获取网站内容,这时我们的行为是地址 >找> 内容。此谓「正向索引」。
- 通过搜索框来找网站时候,通过:内容 >找> 地址
百度搜索直接问问题,而不是找链接..
此谓「倒排索引」。
倒排索引的核心组成
- 当程序向搜索引擎中添加一条文档时候,会通过一种分词算法,将文档数据进行拆分并记录!
- 文档中拆分的单词组成一个
单词表
,并生成一个对应的倒排列表
这都可以在文件中查看的… - 添加的数据,和生成的单词表 单词表,精确记录了,一个单词所拥有的一个文档 id;
-
单词表 和 倒排列表
- 单词词典:记录所有文档的单词,一般都比较大。
还会记录单词到倒排列表的关联信息。
- 倒排列表:记录了单词对应的文档集合,由倒排索引项组成。倒排索引项包含如下信息:
文档ID,用于获取原始信息
单词频率TF,记录该单词在该文档中的出现次数,用于后续相关性算分
分越高,用户最先看到!
位置Position,记录单词在文档中分词的位置,用于语句搜索(phrase query) 偏移Offset,记录单词在文档的开始和结束位置,实现高亮显示,通常在前面加 JS 使其输出页面直接: 高亮显示!
倒排索引的实现
- 当用户通过搜索引擎,去搜索一段话:S1云顶之一最强阵容
当然浏览器并不会,直接通过
S1云顶之一最强阵容
去进行查找,对吧。你百度时候的会出现一模一样的标题吗? - 搜索引擎会对搜索的数据进行拆分,很多关键字:
S1
云顶
最强阵容...
倒排索引进行查找,展示! 另外中文分词还是比较复杂的,不像英文分词一般用空格分隔就可以。可以通过IK 分词器解决
ElasticaSearch安装
Windows 安装非常简单,开箱即用
linux可以参考:ELK实现日志收集器
解压
注意安装解压,在一个没有 空格和中文 的英文目录下!
- bin: 脚本目录,包括:启动、停止等可执行脚本 启动脚本:
elasticsearch.bat
- config: 配置文件目录
- data: 索引目录,存放索引文件的地方
- logs:日志目录
- modules:模块目录,包括了es的功能模块 内置模块
- plugins: 插件目录,es支持插件机制 :
中文分词…等插件!
查看配置:
elasticsearch.yml
cluster.name: wf #配置elasticsearch的集群名称,默认是elasticsearch。建议修改成一个有意义的名称。
node.name: xc_node_1 #节点名,通常一台物理服务器就是一个节点
network.host: 0.0.0.0 #设置绑定主机的ip地址,设置为0.0.0.0表示绑定任何ip,允许外网访问
http.port: 9200 #端口
transport.tcp.port: 9300 #集群结点之间通信端口node.maste
node.master: true #集群中的主节点默认是true,如果原来的master宕机会重新选举新的master.
node.data: true #指定该节点是否存储索引数据,默认为true.
discovery.zen.ping.unicast.hosts: ["0.0.0.0:9300"] #设置集群中master节点的初始列表,多个就逗号隔开配置:["0.0.0.0:9300","0.0.0.0:9200"]
discovery.zen.minimum_master_nodes: 1 #主结点数量的最少值 ,此值的公式为:
node.ingest: true #为了在 indexing(索引)之前预处理 documents(文档)。
bootstrap.memory_lock: false #设置为true可以锁住ES使用的内存,避免内存与swap分区交换数据。
node.max_local_storage_nodes: 2 #单机允许的最大存储结点数,通常单机启动一个结点建议设置为1
#discovery.zen.ping.timeout: 3s #设置ES自动发现节点连接超时的时间,默认为3秒,如果网络延迟高可设置大些。
path.data: D:WSMworkelasticsearchelasticsearchdata #设置插件的存放路径,默认是es根目录下的plugins文件夹
path.logs: D:WSMworkelasticsearchelasticsearchlogs #设置日志文件的存储路径,默认是es根目录下的logs文件夹
http.cors.enabled: true #启动跨域支持!
http.cors.allow-origin: /.*/ #支持各种语言的 origin 跨域, 直接使用内置接口完成开发!
- 集群只是一个概念,其实一台服务器也可以称为集群,
只有一个elasticsearch的集群环境!
jvm.options
无论是 linux 还是 windows 开启时,要指定提供运行的内存… 当然可以直接给一个默认值
在jvm.options中设置 -Xms和-Xmx: 两个值设置为相等 将 Xmx 设置为不超过物理内存的一半。
log4j2.properties
日志文件设置,注意日志级别的配置。
启动:
进入bin目录,在cmd下运行:elasticsearch.bat
浏览器输入:http://localhost:9200
启动页面,也展示着一些信息:lucene_version的版本...
ES快速入门
ES作为一个索引及搜索服务,对外提供丰富的REST接口
- 因此,对于JS 等工程即使没有集成,只要可以发起请求,直接接口调用也可以完成, 开发
创建索引 相当于数据库的 库
关于索引这个语: 索引两个意思 一个文件 一个查找方式
- 索引(名词) ES是基于Lucene构建的一个搜索服务,它要从索引库搜索符合条件索引数据。
- 索引(动词) 索引库刚创建起来是空的,将数据添加到索引库的过程称为索引。
创建索引库:put
put请求 http://localhost:9200/索引库名称
可选参数设置:JSON格式
{
"settings": {
"index": {
"number_of_shards": 1, //分片个数
"number_of_replicas": 0 //备份个数
}
}
}
- number_of_shards:
分片
对于一个大量的数据进行切分,在多台服务器中存放… 不适合单击应用! 设置分片的数量,在集群中通常设置多个分片,表示一个索引库将拆分成多片分别存储不同的结点, 提高了ES的处理能力和高可用性,入门程序使用单机环境,这里设置为1默认为5
- number_of_replicas:
备份,创建两个库存储相同的数据..
设置副本的数量,设置副本是为了提高ES的高可靠性,本次单机环境设置为0,默认值为1
查看索引库:get
创建好了直接 get 相同的地址 就是查看了! , 返回JSON 可以查看信息!
测试:
创建映射 相当于一个 表
/_mapping
注意:
- 6.0之前的版本有type(类型==表名)概念,type相当于关系数据库的表,
- ES官方将在8.0版本中彻底删除type。
暂时把type起一个没有特殊意义的名字.
上边讲的创建索引库相当于关系数据库中的数据库还是表?
- 如果相当于数据库 就表示
一个索引库可以创建很多不同类型的文档
,这在ES中也是允许的。 - 如果相当于表 就表示
一个索引库只能存储相同类型的文档
, ES官方建议,在一个索引库中只存储相同类型的文档。
创建映射 put
put请求: post http://localhost:9200/索引库名称/映射名称(类型,表)/_mapping
- 必须 /_mapping 结尾,JSON 属性参数!
’表’ 属性设置!JSON方式定义:
{
//properties:固定的配置规则
"properties": {
//自定义的列fieid,及类型设置:text keyword...后面详细介绍!
"name": {
"type": "text"
},
"description": {
"type": "text"
},
"studymodel": {
"type": "keyword"
}
}
}
查看映射:get
Get请求: http://localhost:9200/索引库名称
测试:
创建文档 相当于给表添加数据
创建文档 post 或 put
post 或 put 请求: http://localhost:9200/索引名/映射名/id值
- 传入JSON 参数形式,赋值生成一个Document
- 如果不指定id值ES会自动生成一个唯一ID
根据上面的JSON 模拟一个测试JSON
{
"name": "Bootstrap开发框架",
"description": "Bootstrap是由Twitter推出的一个前台页面开发框架,在行业之中使用较为广泛。此开发框架包 含了大量的CSS、JS程序代码,可以帮助开发者(尤其是不擅长页面开发的程序人员)轻松的实现一个不受浏览器限制的 精美界面效果。",
"studymodel": "201001"
}
查询数据:get
Get请求: http://localhost:9200/索引名/映射名/id值
或 http://localhost:9200/索引名/映射名/_search
查询所有数据!及属性信息
搜索文档
- 查询名称中包括spring 关键字的的记录,
还记得上面属性类型 text keyword
text支持拆分关键词查询http://localhost:9200/wsm/w1/_search?q=name:bootstrap
将数据拆分为一组关键词进行查看~ - 查询学习模式为 201001 的记录
http://localhost:9200/wsm/w1/_search?q=studymodel:201001
可以发现studymodel 并不支持关键词拆分查询…
测试:
- took:本次操作花费的时间,单位为毫秒。
- timed_out:请求是否超时
- _shards:说明本次操作共搜索了哪些分片
- hits:搜索命中的记录
- hits.total : 符合条件的文档总数 hits.hits :匹配度较高的前N个文档
- hits.max_score:文档匹配得分,这里为最高分
- _score:每个文档都有一个匹配度得分,按照降序排列。
- _source:显示了文档的原始内容。
分词器 /_analyze
注意:
- 一般只有映射的 text 类型, 才可以使用, 分词器.
- 即:
表的,列类型,必须是 text 才可以使用分词器
keyword 不支持使用;
测试分词器
每次新增数据时候,底层就会默认执行了….
- 在添加文档时会进行分词,索引中存放的就是一个一个的词(term), 当你去搜索时就是拿关键字去匹配词,最终找到词关联的文档。
测试当前索引库使用的分词器: post
post 发送: localhost:9200/_analyze
- text 类型才可以进行分词,而且这里这是测,一段字符数据进行 分词器分词!
- 测试数据:
{"text":"中华人民共和国财政部"}
- 因为 elasticsearch 是老外写的,对中文的分词难免会有不同,所以出现了 IK分词器插件
- elasticsearch: plugins: 插件目录 , 允许集成外部的插件,来完成快速的开发!
IK 分词器测试:post
安装IK分词器插件 点击
post请求没什么变化: localhost:9200/_analyze
- 但是对于,JSON 的测试参数后面需要加一段属性配置:
"analyzer":"ik_max_word"
ik 分词器的规则
- 直接运行测试就直接发现结果数据:更符合咱中国人的感觉!
analyzer 两种分词模式
ik分词器有两种分词模式:ik_max_word
和ik_smart模式
- ik_max_word
精确拆分
最细粒度的拆分
,比如会将:中华人民共和国人民大会堂”拆分为
中华人民共和国、中华人民、中华、华人、人民共和国、人民、共和国、大会堂、大会、会堂等词语。 但这种结果对于搜索引擎并不好,结果多细致,但不能连贯,很难查询到准确的数据! - ik_smart
粗略拆分
最粗粒度的拆分
,比如会将:中华人民共和国人民大会堂”拆分为
中华人民共和国、人民大会堂。 相对来说这样差分的不多,搜索引擎查看的时候,可以更加精确的指定数据!
IK 自定义词库
- 如果要让分词器支持一些专有词语,可以 自定义词库。
- 对于一些 网络热点词汇:吃鸡 云顶… ik 分词器中可能并不会有分词器进行区分… 所以可以支持自定义分词.
Ik 插件安装目录下:config/main.dic 文件夹:
- 可以看到 main.dic文件,中包含了很多常用的关键词,这就是一个Ik的词库
映射 常见的映射类型:
映射维护方法: 表的 CURD 操作
CURD:
- 数据库技术中的缩写词: Create创建 Update修改 Retrieve查看 Delete删除
创建映射 post
一个索引只能有, 不多于一个映射!
post 请求: http://localhost:9200/索引/映射/_mapping
- JSON 参数设置, 字段;
更新映射 post / put
post put 皆可: http://localhost:9200/索引/映射/_mapping
- 就是正常的, 创建到的请求,
把要更新新增的 列直接加入JSON即可
- 但已有字段不允许更新。
如果要强行更改JSON 运行了,
它并不会 包错/移除… 而是直接增加一个你修改的字段, 原字段不受影响!
查询所有索引的映射 get
GET请求: http://localhost:9200/_mapping
- 查询所有的索引映射
- 可以指定索引查看所有 映射 :
http://localhost:9200/索引/_mapping
- 或查看:指定索引/指定映射/_mapping:
http://localhost:9200/索引/映射/_mapping
删除映射 delete
Delete 请求: http://localhost:9200/索引
常用映射类型
- 字符串:字符串包括
text
和keyword
两种类型 - 数字:byte、short、integer、long、float、double、
- 时间:date
- 布尔值boolean: true、false
- 数组: array
- 二进制: binary
text文本字段
- text 可以通过
analyzer
属性指定分词器