DB -- ES
1. 搜索引擎对比
Elasticsearch和Solr
单纯的对已有数据进行搜索时,Solr更快
当实时建立索引时,Solr会产生IO阻塞,查询性能较差,ES具有更明显的优势
随着数据量的增加,Solr的搜索效率会变得更低,而ES不会有明显变化
ES开箱即用(解压就可以用),非常简单,而Solr会复杂一些
Solr利用Zookeeper进行分布式管理,而ES自带分布式协调管理功能
Solr支持多格式数据:json,xml,csv,而ES仅支持json文件格式
solr官方提供的功能更多,而ES更注重本身的核心功能,高级功能会有很多第三方插件提供,例如图形化界面需要Kibana,IK分词器
Solr查询快,但是更新索引时慢(插入删除),用于电商等查询多的应用,ES建立索引快(即查询慢),但实时性查询快
Solr比较成熟,ES更新太快,学习成本高
2. ES安装
要求: jdk1.8以上
下载
https://www.elastic.co/cn/downloads/?elektra=home&storm=hero
目录结构
bin # 启动文件
config # 配置文件
log4j2 # 日志配置文件
jvm.options # jvm配置文件 ,修改该配置文件中的对于内存的配置:Xms256m和Xmx256m
es.yml # es的配置文件 ,默认端口为9200,跨域问题
lib # 相关jar包
models # 功能模块
plugins # 插件
启动
# 启动文件
elasticsearch.bat
{
"name":"" # 主机名
"cluster_name": # 集群名,默认集群开启,一个es也是一个集群
"cluster_uuid": # 在集群中的唯一标识
"version":{
"number":
"build_flavor":
"build_type":
"build_hash":
"build_date":
"build_snapshot":
"lucene_version":
"mininum_wire_compatibility_version":
"mininum_index_compatibility_version"
}
"tagline":"You Know, fro Search"
}
3. 可视化插件安装
环境下载
cnpm下载
http://npm.taobao.org;
cnpm安装
# 安装cnpm
npm install -g cnpm --registry=https://registry.npm.taobao.org
# 创建配置文件
cnpm init -y
# 查看帮助文档
cnpm help package.json
可视化插件下载
https://github.com/mobz/elasticsearch-head
# 官网有下载步骤,默认端口9100
解决跨域问题
elasticsearch.yml
http.cors.enabled:true
http.cors.allow-origin:"*"
重启es服务,并再次来接
4. Kibana可视化平台安装
# kibana版本要和ES版本一致
https://www.elastic.co/cn/downloads/?elektra=home&storm=hero
解压即可
启动
# 启动文件,默认端口5601
kibana.bat
开发者工具
左边图标有一个扳手的图标
汉化
kibana.yml
i18n.locale:"zh-CN"
重启kibana
5. IK分词器插件
分词:就是将一段中文或英文分成一个个的关键字,在搜索的时候会把自己的信息进行分词,会将索引库中的数据进行分词,然后进行一个匹配操作,默认的中文分词是将每一个中文作为一个词,这显然不合逻辑,所以需要安装中文分词器IK来解决这个问题
IK提供了两个分词算法:ik_samrt和ik_max_word,其中ik_smart为最少切分,ik_max_word为最细粒度划分
下载
# 下载完毕,键文件夹,放到ES的plugins文件夹中
https://github.com/medcl/elasticsearch-analysis-ik/releases
重启ES
查看是否安装成功
ES的启动界面会有加载IK的日志
# 命令行
elasticsearch-plugin
6. Kibana交互ES
# 可以使用kibana的开发者工具,和ES交互
# 选择分词算法
GET _analyze # get请求
{
"analyzer":"ik_smart", # 选择分词算法
"text": "美特斯邦威"
}
GET _analyze # get请求
{
"analyzer":"ik_max_word", # 选择分词算法
"text": "美特斯邦威"
}
# 可能ik分词器的字典中不存在我想要的分词,这样就需要自己手动添加了
7. IK分词器自定义分词
# ES的plugin下的ik分词器中的config目录中新建一个自定义分词字典(xxx.dic)
# ES的plugin下的ik分词器中的config目录中的IKAnalyzer.ofg.xml文件导入该dic
<entry key="ext_dict">xxx.dic</entry>
重启ES
8. ES的CRUD(Restful)
索引操作
GET
# 查询文档,通过文档ID
# ip:9200/索引名称/类型名称/文档id 类型名8.0已弃用
ip:9200/索引名称/文档id
# ip:9200/_cat/health 查看健康信息
# ip:9200/_cat/indices?v 查看ES中的所有信息
POST
# 创建文档,随机文档ID
ip:9200/索引名称 8.0已弃用
# 修改文档,每修改一次,version会增加1,表示改动的次数(推荐使用,可以只修改特定字段)
ip:9200/索引名称/文档id/_update(_update是关键字)
{
"doc":{
字段:值
}
}
# 查询所有数据
ip:9200/索引名称/_search(_search是关键字)
# 创建成功,服务端返回成功状态信息,created
PUT
# 创建文档,指定文档ID
ip:9200/索引名称/文档id
{
字段:值,
...
}
# 修改文档,每修改一次,version会增加1,表示改动的次数,但是如果提交的json字段和原有的字段不是一一对应,会覆盖原数据,不建议使用这种方式修改
ip:9200/索引名称/文档id
{
字段:值,
...
}
DELETE
# 删除文档,指定文档ID
ip:9200/索引名称/文档id
文档操作
GET
# 查询文档,通过文档ID
# ip:9200/索引名称/类型名称/文档id 类型名8.0已弃用
ip:9200/索引名称/文档id
# 根据条件查询,如果字段类型为keyword,必须是完全相同的字符才能被匹配
ip:9200/索引名称/类型名称/_search?q=字段名:值&字段名2:值2
# 修改请求体,达到复杂查询的目的
ip:9200/索引名称/类型名称/_search
{
"query":{
"match":{
"字段名":"值"
}
}
"_source":["name","field"] # 字段过滤
"sort":[ # 排序,根据字段排序
{
"字段":{
"order":"desc"
}
}
]
"from":0 # 分页,起始值
"size":1 # 分页,一页几条数据
}
# 查询结果结构
hit:索引和文档的信息,如果有多个匹配项是个列表
score:分数,可以判断谁的权重更高,用来排序
# must,类似and,查询结果必须包含must字段中指定的的值
{
"query":{
"bool":{
"must":[
"match":{
"字段名":"值"
},
"match":{
"字段名":"值"
}
]
}
}
}
# should,类似or
{
"query":{
"bool":{
"should":[
"match":{
"字段名":"值"
},
"match":{
"字段名":"值"
}
]
}
}
}
# must_not 类似(not)
{
"query":{
"bool":{
"must_not":[
"match":{
"字段名":"值"
},
"match":{
"字段名":"值"
}
]
}
}
}
# 过滤器(filter)
{
"query":{
"bool":{
"must":[
"match":{
"字段名":"值"
},
]
"filter":{
"range":{
"字段":{
"gt"
"lt"
"gte":
"lte":
}
}
}
}
}
}
# 多条件查询,可以制定score来进一步过滤
{
"query":{
"match":{
"字段":"值1 值2" # 多条件空格分隔
}
}
}
# term:直接通过倒排索引指定的词条进行精确查找
{
"query":{
"term":{
"字段":"值1 值2" # 多条件空格分隔
}
}
}
# 高亮查询,指定的高亮字段,会自动加<em>搜索结果<em>
{
"query":{
"match":{
"字段":"值1 值2" # 多条件空格分隔
}
}
"highlight":{ # 高亮功能
"pre_tags":"<p class='key' style='color:red'>", # 自定义高亮的标签格式开头
"post_tags":"</p>", # 指定高亮的标签格式闭合标签
"fields":{ # 设置高亮字段
"字段":{} #空字典就可以了
}
}
}
查询总结
# 关于分词
term:倒排索引精确查找
match:会使用分词器解析,先分析文档,再进行查询
# 关于类型
keyword # keyword类型是关键字,会把整个keyword当做一个整体精确查询,
text # text类型会模糊查询
9. ES设置
数据类型
# 字符串
text # 文本,会模糊匹配,只要包含就可以匹配的到
keyword # 关键字,如果是keyword类型,被查询时会被精准匹配,不会被拆分
# 数值类型
long
integer
short
byte
double
float
half
float
scaled
# 日期类型
date
# 布尔值类型
boolean
# 二进制类型
binary
数据类型设置
# 设置数据类型,如果未设置,底层会自动匹配类型
PUT /test2 # 创建test2索引
{
"mappings":{ # 规则
"properties":{ # 属性
"name":{
"type":"text" # 设置name字段为text类型
},
"age":{
"type":"long" # 设置age字段为long类型
},
"birthday":{
"type":"date" # 设置birthday字段为date类型
}
}
}
}
# 获取索引结构
get test2
10. ES基本概述
ES结构
# ES是面向文档的,关系型数据库和ES的对比:
库 索引
表 types(#8.0已被弃用)
行 documents(最小单位)
字段 fields
物理设计
ES在后台把每个索引划分成多个分片,每个分片可以在集群中的不同服务器间迁移
11. 底层分析
节点和分片
一个集群至少有一个节点,而一个节点就是一个ES进程,节点可以有多个ES索引,如果创建ES索引,ES索引将有5个分片(Lucene索引)构成,主分片有一个副本,对于多节点的集群创建ES索引时,主分片和对应的复制分片不会在同一个节点内,这样当某一节点挂了,数据不会丢失实际上一个分片就是一个Lucene索引,一个包含倒排索引的文件目录
倒排索引
ES使用的是倒排索引结构,采用lucene倒排索引为底层,这种结构适用于快速的全文搜索,不扫描全部文档就可以搜索到对应内容,一个索引由文档中所有不重复的列表构成,对于每一个词,都有一个包含它的文档列表,如文档1中的内容是1,2,3 文档2的内容是2,3,5,为了创建索引,会将每个文档拆分成独立的词(词条),然后创建一个包含所有不重复的词条的排序列表,然后列出每个词条出现在哪个文档,如1在文档1中出现,文档2没有,2两个文档都有,3也是两个文档都有,5在文档1中没有,文档2中有,假如搜索1和2的时候,只需要查看每个词条的文档,如1在文档1中有,文档2中没有,2在文档1和文档2中都有,那么说明文档1的score更高,匹配程度更高,如果没有别的条件,这两个包含关键字的文档都将返回
也就是对文档的内容进行分词拆分,列出包含分词的文档ID,当查询的时候,直接查包含分词的文档ID就可以了,根本不会产生无用搜索
12. 应用场景
海量日志分析
商品价格监控网站
如果价格低于50会自动通知到用户
数据分析
python防脱发技巧

浙公网安备 33010602011771号