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会自动通知到用户

数据分析

posted @ 2023-03-27 20:58  河图s  阅读(21)  评论(0)    收藏  举报