Elasticsearch搜索引擎

1、初识Elasticserch

1.1 简介

  • 是一款非常强大的开源搜索引擎,可以用来实现搜索、日志统计、分析、系统监控等功能
  • 结合kibana、Logstash、Beats,也就是elastic stack(ELK)- 以elasticserch为核心的技术栈。
  • elasticsearch是elastic stack的核心,负责存储、搜索、分析数据,基于Luncene实现。

1.2 Lucene

​ Lucene是一个Java语言的搜索引擎类库,提供了搜索引擎的核心API,是Apache公司的顶级项目。官网地址

优势

  • 易扩展
  • 高性能(基于倒排索引)

劣势

  • 只限于java开发
  • 学习曲线陡峭
  • 不支持水平扩展

2、正向索引和倒排索引

传统数据库(如MySQL)采用正向索引,例如某张表以id创建索引。

elasticsearch采用倒排索引

  • 文档(document):每条数据就是一个文档

  • 词条(term):文档按照语义分成的词语,得到的词语就是词条

正向索引

​ 基于文档id创建索引。查询词条时必须先找到文档,而后判断是否包含词条

倒排索引

​ 对文档内容分词,对词条创建索引,并记录词条所在文档的信息。查询时先根据词条查询到文档id,而后获取到文档

3、ES的基本概念

3.1 文档

elasticsearch是面向文档存储的,可以是数据库中的一条商品数据,一个订单信息。

文档数据会被序列化为json格式后存储在elasticsearch中。

3.2 索引

  • 索引(index):相同类型的文档的集合

  • 映射(mapping):索引中文档的字段约束信息,类似表的结构约束。

3.3 概念对比

MySQL Elasticserch 说明
Table Index 索引(index),就是文档的集合,类似数据库的表(table)
Row Document 文档(Document),就是一条条的数据,类似数据库中的行(Row),文档都是JSON格式
Column Field 字段(Field),就是JSON文档中的字段,类似数据库中的列(Column)
Schema Mapping Mapping(映射)是索引中文档的约束,例如字段类型约束。类似数据库的表结构(Schema)
SQL DSL DSL是elasticsearch提供的JSON风格的请求语句,用来操作elasticsearch,实现CRUD

3.4 架构

Mysql:擅长事务类型操作,可以确保数据的安全和一致性

Elasticsearch:擅长海量数据的搜索、分析、计算

4、安装elasticserch、kibana

参考Elasticserch安装

5、分词器

5.1 默认分词器

es在创建倒排索引时需要对文档分词;在搜索时,需要对用户输入内容分词。但默认的分词规则中文处理并不友好

通过kibana的DevTools工具进行测试:

1
2
3
4
5
6
#测试分词器
POST /_analyze
{
"text":"测试IK分词器的效果",
"analyzer": "standard"
}

语法说明:

  • POST:请求方式
  • /_analyze:请求路径,这里省略了http://192.168.150.101:9200,有kibana帮我们补充
  • 请求参数,json风格:
    analyzer:分词器类型,这里是默认的standard分词器
      text:要分词的内容
    

5.2 IK分词器

处理中文分词,一般会使用IK分词器。查看官网

安装IK分词器,参考资料Elasticsearch安装

ik分词器拓展词库,参考资料Elasticsearch安装

ik分词器停用词库,参考资料Elasticsearch安装

ik分词器包含两种模式:

  • ik_smart:最少切分,粗粒度
  • ik_max_word:最细切分,细粒度

6、索引库操作

6.1 mapping属性

mapping是对索引库中文档的约束,常见的mapping属性包括:

  • type:字段数据类型,常见的简单类型有:

    • 字符串:text(可分词的文本)、keyword(精确值,例如:品牌、国家、ip地址)

    • 数值:long、integer、short、byte、double、float、

    • 布尔:boolean

    • 日期:date

    • 对象:object

  • index:是否创建索引,默认为true

  • analyzer:使用哪种分词器

  • properties:该字段的子字段

6.2 创建索引库

ES中通过Restful请求操作索引库、文档。请求内容用DSL语句来表示。创建索引库和mapping的DSL语法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
PUT /索引库名称
{
  "mappings": {
    "properties": {
      "字段名":{
        "type""text",
        "analyzer""ik_smart"
      },
      "字段名2":{
        "type""keyword",
        "index""false"
      },
      "字段名3":{
        "properties": {
          "子字段": {
            "type""keyword"
          }
        }
      },
// ...略
    }
  }
}

index属性默认为true,会创建索引

示例:

6.3 查看、删除索引库

1
2
3
4
5
#查看索引库
GET /索引库名 #示例:GET /member

#删除索引库
DELETE /索引库名

6.4 修改索引库

索引库和mapping一旦创建无法修改,但是可以添加新字段,语法如下:

1
2
3
4
5
6
7
8
PUT /索引库名/_mapping
{
  "properties": {
    "新字段名":{
      "type": "integer"
    }
  }
}

7、文档操作

7.1 添加文档

新增文档的DSL语法如下:

1
2
3
4
5
6
7
8
9
10
POST /索引库名/_doc/文档id
{
    "字段1": "值1",
    "字段2": "值2",
    "字段3": {
        "子属性1": "值3",
        "子属性2": "值4"
    },
// ...
}

示例:

7.2 查询、删除文档

1
2
3
4
5
#查看文档
GET /索引库名/_doc/文档id #示例:GET /member/_doc/1

#删除索引库
DELETE /索引库名/_doc/文档id

7.3 修改文档

7.3.1 全量修改

全量修改会删除旧文档,添加新文档

1
2
3
4
5
6
PUT /索引库名/_doc/文档id
{
    "字段1": "值1",
    "字段2": "值2",
// ... 略
}

7.3.2 增量修改

增量修改,修改指定字段值

1
2
3
4
5
6
POST /索引库名/_update/文档id
{
    "doc": {
"字段名": "新的值",
}
}

7.4 动态映射

如果新增文档的结构与mapping结构不一致,会报什么错误?

当我们向ES中插入文档时,如果文档中字段没有对应的mapping,ES会帮助我们字段设置mapping,规则如下:

JSON类型 Elasticserch类型
字符串 •日期格式字符串:mapping为date类型
•普通字符串:mapping为text类型,并添加keyword类型子字段Document
布尔值 boolean
浮点数 float
整数 long
对象嵌套 object,并添加properties
数组 由数组中的第一个非空类型决定
空值 忽略

• 插入文档时,es会检查文档中的字段是否有mapping,如果没有则按照默认mapping规则来创建索引。

• 如果默认mapping规则不符合你的需求,一定要自己设置字段mapping

8、RestClient操作索引库

8.1 RestClient

ES官方提供了各种不同语言的客户端,用来操作ES。这些客户端的本质就是组装DSL语句,通过http请求发送给ES。点击这里查看官方文档

8.2 JavaRestClient操作索引库

利用JavaRestClient实现创建、删除索引库,判断索引库是否存在。需求:根据提供的酒店数据创建索引库,索引库名为hotel,mapping属性根据数据库结构定义。

8.2.1 Demo准备

8.2.1.1、创建hotel表,并导入数据

参考hotel数据模板