elasticsearch(ES)是一款非常强大的开源搜索引擎,可以帮助我们从海量的数据中快速找到需要的内容。
elastic stack(ELK):elasticsearch结合kibana、Logstash、Beats。被广泛的应用在日志数据分析、实时监控等领域。
Kibana:数据的可视化都可以被取代,每个大公司都有自己的网站可视化工具。
Logstash 和Beats:负责将数据投喂给ElasticSearch来存储,计算和搜索
那么这些工具当中最不能被替代的当然后Elasticsearch了。几乎所有的分布式搜索都用着ES。数据的分析都必须走ES,ES不能被替代
ES是基于Lucene开发的
二 、正排索引和倒排索引
正排索引
正排索引是指将数据按其自然顺序存储,并为每个数据项维护一个指向该数据项位置的指针。它通常用于以下场景:
-
应用场景:
- 数据库管理系统(如关系型数据库)
- 需要快速访问完整记录的场景
-
优点:
- 查询速度快,尤其是对范围查询(例如查找某个字段值在某个范围内的记录)非常有效。
- 数据插入和更新操作相对简单。
-
缺点:
- 对于全文搜索和复杂查询,性能较差,因为需要遍历整个数据集。
倒排索引
倒排索引是一种将文档中的词汇与包含这些词汇的文档的列表进行映射的数据结构。它特别适用于文本搜索和信息检索。
-
应用场景:
- 搜索引擎
- 文本检索系统
- 需要快速查找包含特定关键词的文档的场景
-
优点:
- 可以快速找到包含特定词汇的所有文档,支持高效的关键词搜索。
- 适合处理大量文本数据,支持复杂查询(如布尔查询)。
-
缺点:
- 需要额外的存储空间来维护索引。
- 更新和删除操作相对复杂,因为需要维护索引的准确性。
总结
- 正排索引适合需要快速访问完整记录的情况,优于范围查询。
- 倒排索引则适合文本检索,能够高效支持关键词搜索
自己的理解
正排索引:通过检索全部数据(例如mysql的每行,有很多行数据)将每一行的数据与关键字比对,如果匹配则添加到返回序列当中。
倒排索引:
两个字段:词条和文档id()
词条:包含一个文档中的一些关键字(文档按照语义分成的词语)
文档id:包含这个关键字的文档(一行数据)
当查询一个关键字,不是与整个数据集进行一一比对,而是与词条进行比较,并且词条是唯一的,可以将词条建索引,这样关键字与词条进行比对会很快。
三、认识ES
文档:可以是数据库中的一条商品数据,一个订单信息
文档数据会被序列化为json格式存储到elasticsearch当中
索引:相同类型的文档的集合(例如商品是一类集合,订单是一类集合)
映射:索引中文档字段的约束信息,类似表的数据约束
mysql和ES概念的对比
ES和mysql的架构
mysql:擅长事务类型操作,可以确保数据的安全和一致性
ES:擅长海量数据的搜索、分析、计算
如何选择
-
使用 MySQL:
- 当数据需要严格一致性,并且需要复杂的关系查询时。
- 适合传统的业务系统。
- 保存安全可靠的数据
-
使用 Redis:
- 当需要高速缓存、实时数据处理或简单的键值存储时。
- 适合高并发场景和需要低延迟的应用。
-
使用 Elasticsearch:
- 当需要强大的搜索性能和复杂查询能力时,尤其是对文本数据。
- 适合需要处理和分析大规模日志数据的应用
5、分词器:
ik分词器有两种分词方式:
-
ik_smart
:最少切分 : 占用内存少,但是查找某些词找不到这句话 -
ik_max_word
:最细切分 :占用内存多,很多词都可以找到这句话,粒度更细
GET /_analyze
{
"analyzer": "ik_max_word",
"text": "黑马程序员学习java太棒了"
}
GET /_analyze
{
"analyzer": "ik_smart",
"text": "黑马程序员学习java太棒了"
}
分词器的作用:
1、创建倒排索引时对文档分词
2、用户搜索时,对输入的内容分词
IK分词器模式:
1、ik_smart:智能切分,粗粒度
2、ik_max_word:最细切分,细粒度
IK分词器如何拓展词条,如何停用:
1、利用config目录的IkAnalyzer.cfg.xml文件添加拓展词典和停用词典
2、在词典中添加拓展词条或者停用词条
6、Mapping(类型,每个数据是什么类型)是对索引库中文档的约束,Mapping常见属性:
1、type:字段的数据类型,常见的简单类型有:
-
字符串:text(可分词的文本)、keyword(精确值,不需要分词)
-
数值:long、integer、short、byte、double、float
-
布尔:boolean
-
日期:Date
-
对象:object
2、index:是否创建倒排索引(创建索引是为了查找,有些词不需要查找),默认为true
3、analyzer:使用那种分词器(和text类型配合使用)
4、properties:该字段的子字段
bash
GET _search
{
"query": {
"match_all": {}
}
}
GET /
# 分析值,默认的分词器standard
POST /_analyze
{
"text": "cc,是个好学生",
"analyzer": "standard"
}
# 分词,IK分词器的最细粒度
GET /_analyze
{
"analyzer": "ik_max_word",
"text": "黑马程序员学习java太棒了"
}
#分词,IK分词器粗粒度
GET /_analyze
{
"analyzer": "ik_smart",
"text": "黑马程序员学习java太棒了"
}
#通过新增词语来进行分词
GET /_analyze
{
"analyzer": "ik_smart",
"text": "传智教育的java太棒了"
}
#创建一个索引库,类似于表
PUT /cc
{
"mappings":
{
"properties": {
"info":{
"type": "text",
"analyzer": "ik_smart"
},
"email":{
"type": "keyword",
"index": false
},
"name":{
"type": "object",
"properties": {
"firstName":{
"type":"keyword"
},
"lastName":{
"type":"keyword"
}
}
}
}
}
}
#查询索引库
GET /cc
#往索引库中新增一个字段
PUT /cc/_mapping
{
"properties":{
"age":{
"type":"integer",
"index":false
}
}
}
#删除一个索引库,慎重操作
DELETE /cc
#往索引库中添加文档(一行数据),'1'为索引id,不添加会有一个默认值
POST /cc/_doc/1
{
"info":"cc,你真的很菜啊",
"email":"3363702067@qq.com",
"name":
{
"firstName":"rong",
"lastName":"li"
}
}
#查询某个索引库中的某个id的值
GET /cc/_doc/1
#删除索引库中的某个id值
DELETE /cc/_doc/1
#全量修改,将所以字段都修改也是一直覆盖,如果存在则是修改,不存在则是新增
PUT /cc/_doc/1
{
"info":"cc,你真的很lajia啊",
"email":"3363702067@qq.com",
"name":
{
"firstName":"rong",
"lastName":"li"
}
}
#局部修改,只更新某个字段的值
POST /cc/_update/1
{
"doc": {
"email":"cc"
}
}
ES的文档操作:
ES依赖:
<!--es-->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
</dependency>