文章目录
- 1.elasticsearch基础
 - 索引和映射
 - 索引库操作
 - 索引库操作总结
 
- 文档操作
 - 文档操作总结
 
- RestAPI
 - RestClient操作文档
 
1.elasticsearch基础
什么是elasticsearch?
- 一个开源的分布式搜索引擎,可以用来实现搜索、日志统计、分析、系统监控等功能
 
什么是elastic stack(ELK)?
- 是以elasticsearch为核心的技术栈,包括beats、Logstash、kibana、elasticsearch
elasticsearch结合kibana、Logstash、Beats,也就是elastic stack(ELK)。被广泛应用在日志数据分析、实时监控等领域

倒排索引:
倒排索引的概念是基于MySQL这样的正向索引而言的。
那么什么是正向索引呢?例如给下表(tb_goods)中的id创建索引:

如果是根据id查询,那么直接走索引,查询速度非常快。 
但如果是基于title做模糊查询,只能是逐行扫描数据,流程如下:
1)用户搜索数据,条件是title符合"%手机%"
2)逐行获取数据,比如id为1的数据
3)判断数据中的title是否符合用户搜索条件
4)如果符合则放入结果集,不符合则丢弃。回到步骤1
逐行扫描,也就是全表扫描,随着数据量增加,其查询效率也会越来越低。当数据量达到数百万时,就是一场灾难。
倒排索引中有两个非常重要的概念:
- 文档(
Document):用来搜索的数据,其中的每一条数据就是一个文档。例如一个网页、一个商品信息 - 词条(
Term):对文档数据或用户搜索数据,利用某种算法分词,得到的具备含义的词语就是词条。例如:我是中国人,就可以分为:我、是、中国人、中国、国人这样的几个词条 
创建倒排索引是对正向索引的一种特殊处理,流程如下:
- 将每一个文档的数据利用算法分词,得到一个个词条
 - 创建表,每行数据包括词条、词条所在文档id、位置等信息
 - 因为词条唯一性,可以给词条创建索引,例如hash表结构索引
 

 倒排索引的搜索流程如下(以搜索"华为手机"为例):
1)用户输入条件"华为手机"进行搜索。
2)对用户输入内容分词,得到词条:华为、手机。
3)拿着词条在倒排索引中查找,可以得到包含词条的文档id:1、2、3。
4)拿着文档id到正向索引中查找具体文档。
如图:

 虽然要先查询倒排索引,再查询对应的正排索引,但是无论是词条、还是文档id都建立了索引,查询速度非常快!无需全表扫描。
正向索引:
- 优点: 
  
- 可以给多个字段创建索引
 - 根据索引字段搜索、排序速度非常快
 
 - 缺点: 
  
- 根据非索引字段,或者索引字段中的部分词条查找时,只能全表扫描。
 
 
倒排索引:
- 优点: 
  
- 根据词条搜索、模糊搜索时,速度非常快
 
 - 缺点: 
  
- 只能给词条创建索引,而不是字段
 - 无法根据字段做排序
 
 
elasticsearch是面向**文档(Document)**存储的,可以是数据库中的一条商品数据,一个订单信息。文档数据会被序列化为json格式后存储在elasticsearch中:
索引和映射
索引(Index),就是相同类型的文档的集合。
例如:
- 所有用户文档,就可以组织在一起,称为用户的索引;
 - 所有商品的文档,可以组织在一起,称为商品的索引;
 - 所有订单的文档,可以组织在一起,称为订单的索引;
 
- Mysql:擅长事务类型操作,可以确保数据的安全和一致性
 - Elasticsearch:擅长海量数据的搜索、分析、计算

 
索引库操作
mapping映射属性:
 
 
创建索引库和映射:
基本语法:
- 请求方式:PUT
 - 请求路径:/索引库名,可以自定义
 - 请求参数:mapping映射
 
查询索引库:
基本语法:
- 请求方式:GET
 - 请求路径:/索引库名
 - 请求参数:无
 
修改索引库:
 倒排索引结构虽然不复杂,但是一旦数据结构改变(比如改变了分词器),就需要重新创建倒排索引,这简直是灾难。因此索引库一旦创建,无法修改mapping。
虽然无法修改mapping中已有的字段,但是却允许添加新的字段到mapping中,因为不会对倒排索引产生影响。
 
 删除索引库:
- 请求方式:DELETE
 - 请求路径:/索引库名
 - 请求参数:无
 
索引库操作总结
索引库操作有哪些?
- 创建索引库:PUT /索引库名
 - 查询索引库:GET /索引库名
 - 删除索引库:DELETE /索引库名
 - 添加字段:PUT /索引库名/_mapping
 
文档操作
新增文档:
 
查询文档
 
 删除文档:
 
 修改文档:
修改有两种方式:
- 全量修改:直接覆盖原来的文档
 - 增量修改:修改文档中的部分字段
 
全量修改:
 全量修改是覆盖原来的文档,其本质是:
- 根据指定的id删除文档
 - 新增一个相同id的文档
 
注意:如果根据id删除时,id不存在,第二步的新增也会执行,也就从修改变成了新增操作了。
 
 增量修改:
 增量修改是只修改指定id匹配的文档中的部分字段。
 
文档操作总结
-  
创建文档:POST /{索引库名}/_doc/文档id { json文档 }
 -  
查询文档:GET /{索引库名}/_doc/文档id
 -  
删除文档:DELETE /{索引库名}/_doc/文档id
 -  
修改文档:
- 全量修改:PUT /{索引库名}/_doc/文档id { json文档 }
 - 增量修改:POST /{索引库名}/_update/文档id { “doc”: {字段}}
 
RestAPI
- 向数据库导入数据

 
 
- 配置

 - 索引库设计
 
PUT /hotel
{
  "mappings": {
    "properties": {
      "id": {
        "type": "keyword"
      },
      "name":{
        "type": "text",
        "analyzer": "ik_max_word",
        "copy_to": "all"
      },
      "address":{
        "type": "keyword",
        "index": false
      },
      "price":{
        "type": "integer"
      },
      "score":{
        "type": "integer"
      },
      "brand":{
        "type": "keyword",
        "copy_to": "all"
      },
      "city":{
        "type": "keyword",
        "copy_to": "all"
      },
      "starName":{
        "type": "keyword"
      },
      "business":{
        "type": "keyword"
      },
      "location":{
        "type": "geo_point"
      },
      "pic":{
        "type": "keyword",
        "index": false
      },
      "all":{
        "type": "text",
        "analyzer": "ik_max_word"
      }
    }
  }
}
 
几个特殊字段说明:
- location:地理坐标,里面包含精度、纬度
 - all:一个组合字段,其目的是将多字段的值 利用copy_to合并,提供给用户搜索
 
- 初始化RestClient
在elasticsearch提供的API中,与elasticsearch一切交互都封装在一个名为RestHighLevelClient的类中,必须先完成这个对象的初始化,建立与elasticsearch的连接。
 - 创建索引库

 
删除索引库:
 
 判断索引库是否存在:
 
RestClient操作文档
首先要将数据库的酒店数据查询出来,写入elasticsearch中(按照索引库的mapping的规则)。
 
 新增文档的DSL语句如下:
 
 
 查询文档:
 
 
 删除文档:
 
 
 修改文档:
 在RestClient的API中,全量修改与新增的API完全一致,判断依据是ID:
- 如果新增时,ID已经存在,则修改
 - 如果新增时,ID不存在,则新增
 

 批量处理:
 批量处理BulkRequest,其本质就是将多个普通的CRUD请求组合在一起发送。
 
总结:
文档操作的基本步骤:
- 初始化RestHighLevelClient
 - 创建XxxRequest。XXX是Index、Get、Update、Delete、Bulk
 - 准备参数(Index、Update、Bulk时需要)
 - 发送请求。调用RestHighLevelClient#.xxx()方法,xxx是index、get、update、delete、bulk
 - 解析结果(Get时需要)
 



















