Elasticsearch(一)
初始ES
什么是Elasticsearch
学习ES首先要认识他是个什么,能够为我们带来哪些便利:
- elasticsearch是一款非常强大的开源搜索引擎,可以帮助我们从海量数据中快速找到需要的内容;
- elasticsearch结合kibana、Logstash、Beats,也就是elasticstack(ELK)。被广泛应用在日志数据分析、实时监控
等领域; - elasticsearch是elastic stack的核心,负责存储、搜索、分析数据;
lucene
lucene又是个什么东西呢?说白了就是我们ES运行的底层,ES底层运行的就是lucene,lucene是Java语言的搜索引擎类库,是Apache公司的顶级项目,官网:lucene官网
为什么ES使用lucene?
lucene优缺点又是什么呢?
lucene优势
- 易扩展,易扩展性是因为lucene使用的restful格式,请求方式使用http的方式即可
- 高性能(基于倒排索引)
lucene缺点 - 只限于Java
- 学习曲线陡峭
- 不支持水平扩展
倒排索引
正向索引
- 传统数据库(如mysql)采用正向索引,例如使用表的id创建索引;
- 比如搜索‘手机’,正向索引会逐条扫描,判断是否包含‘手机’,如果包含就存储结果集中,不包含则丢弃,如果数据库有1000万数据,则需要扫描1000万次,效率很低;
倒排索引
倒排索引主要就是以下两个名词:
- 文档:每条数据就是一个文档,如分类表,一个分类就是一个文档;
- 词条:文档按照语义分成的词语,如下图,小米是一个词条,手机是一个词条,充电器是一个词条;
倒排索引会产生新的一个表,表中包含两个字段词条 和 文档id
倒排索引完成后如下图,如果有更多的词条,继续往下存即可
倒排索引表有了,那么我们又怎么去查呢?
es查询其实是经过了两次查询
- 根据词条去搜素倒排索引,查询出文档id
- 根据文档id查询
在查询过程中还可以根据出现频率高的文档id进行排序,可以将出现频率高的放在前面
ES安装
安装就不做过多讲解
IK分词器的拓展和停用字典
随着网络和社会的发展,新出现的词是不在IK分词器字典中的,这就出现了一个问题:如何拓展IK词库?
要拓展ik分词器的词库,只需要修改一个ik分词器目录中的config目录中的lkAnalyzer.cfg.xml文件:
- ext_dic:扩展字典
- ext_stopwords:停止词字典,比如国家领导人等敏感词汇
这两个在IK的config文件中没有,就需要自己新建这两个文件
配置完成后需要重启ES才能生效
操作索引库-mapping属性
我们知道在ES中有索引库的概念,这个东西就是数据库里面的表,而索引库中有很多的文档,这个文档就像数据库中一行一行的数据
,我们知道数据库要先创建表才能去添加数据,那么ES也需要现有索引库才能去添加文档,我们先来学习一下索引库的一些操作。
mapping属性
mapping是对索引库中文档的约束,常见的mapping属性包括
- type:字段数据类型,常见的简单类型有
- 字符串
- text(可分词的文本)
- keyword(精确值,例如:品牌、国家、ip地址)
- 数值:long、integer、short、byte、double、float
- 布尔:boolean
- 日期:date
- 对象:object
- 字符串
- index:是否创建索引,默认为true,true为开启倒排索引,true时所有的字段都参与搜索,可以针对于某个字段进行设置,如果该字段不涉及到搜索,可以将该字段的index设置为false
- analyzer:使用哪种分词器,analyzer其实是针对于text使用的其他keyword不需要使用
- properties:该字段的子字段,可以用properties指定字段的子属性
操作索引库-创建索引库
创建索引库
ES中通过Restful请求操作索引库、文档。请求内容用DSL语句来表示。创建索引库和mapping的DSL语法如下:
查看索引库
GET /索引库名
删除索引库
DELETE /索引库名
修改索引库
在ES中是禁止修改索引库的
索引库和mapping一旦创建无法修改,但是可以添加新的字段,语法如下:
这个字段名一定是一个新的,如果和已经有的重名了,就会报错
文档操作-新增、查询、删除文档
新增文档(添加数据)
新增文档的DSL语法:
POST /索引库名/_doc/文档id
{
"字段1":"值1",
"字段2":"值2",
"字段3":{
"子属性1":"值3",
"子属性2":"值4",
}
}
查询文档(查询数据)
GET /索引库名/_doc/文档id
删除文档(删除数据)
DELETE /索引库名/_doc/文档id
修改文档
- 方式一:全量修改,会删除旧文档,添加新文档
PUT /索引库名/_doc/文档id
{
"字段1":"值1",
"字段2":"值2",
"字段3":{
"子属性1":"值3",
"子属性2":"值4",
}
}
- 方式二:增量修改,修改指定字段值
POST /索引库名/_update/文档id
{
"doc": {
"字段名": "新的值"
}
}