elasticsearch学习六:学习 全文搜索引擎 elasticsearch的语法,使用kibana进行模拟测试(持续更新学习)

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
云原生数据库 PolarDB PostgreSQL 版,标准版 2核4GB 50GB
云原生数据库 PolarDB MySQL 版,通用型 2核4GB 50GB
简介: 这篇文章是关于Elasticsearch全文搜索引擎的学习指南,涵盖了基本概念、命令风格、索引操作、分词器使用,以及数据的增加、修改、删除和查询等操作。

前言

一、基本概念

  1. 全文搜索 属于最常见的需求,开源的 Elasticsearch (以下简称 Elastic)是目前全文搜索引擎的首选。
  2. 它可以快速地储存、搜索和分析海量数据。维基百科、Stack Overflow、Github 都采用它。
  3. Elastic 的底层是开源库 Lucene。但是,你没法直接用 Lucene,必须自己写代码去调用它的接口。Elastic 是 Lucene 的封装提供了 REST API 的操作接口,开箱即用

1. Node节点 与 Cluster集群

Elastic 本质上是一个分布式数据库,允许多台服务器协同工作,每台服务器可以运行多个 Elastic 实例。
单个 Elastic 实例称为一个节点(node)。一组节点构成一个集群(cluster)。

2. Index 索引

Elastic 会索引所有字段,经过处理后写入一个反向索引(Inverted Index)。查找数据的时候,直接查找该索引。
所以,Elastic 数据管理的顶层单位就叫做 Index(索引)。它是单个数据库的同义词。每个 Index (即数据库)的名字必须是小写。
下面的命令可以查看当前节点的所有 Index。
GET /_mapping?pretty=true
在这里插入图片描述

3. Document文档

Index 里面单条的记录称为 Document(文档)。许多条 Document 构成了一个 Index。
Document 使用 JSON 格式表示,下面是一个例子。

{
  "user": "张三",
  "title": "工程师",
  "desc": "数据库管理"
}

同一个 Index 里面的 Document,不要求有相同的结构(scheme),但是最好保持相同,这样有利于提高搜索效率。

4. Type类型

Document 可以分组,比如 weather 这个 Index 里面,可以按城市分组(北京和上海),也可以按气候分组(晴天和雨天)。这种分组就叫做 Type,它是虚拟的逻辑分组,用来过滤 Document。

不同的 Type 应该有相似的结构(schema),举例来说,id 字段不能在这个组是字符串,在另一个组是数值。这是与关系型数据库的表的一个区别。性质完全不同的数据(比如productslogs)应该存成两个 Index,而不是一个 Index 里面的两个 Type(虽然可以做到)。

下面的命令可以列出每个 Index 所包含的 Type。(和上面截图一样)
GET /_mapping?pretty=true
根据规划,Elastic 6.x 版只允许每个 Index 包含一个 Type,7.x 版将会彻底移除 Type。

5. 逻辑对比

上面说的 集群,节点,索引,类型,文档,分片(底层封装),映射 是什么呢?

怎么区分对比 非关系型数据库 elasticsearch 和 关系型数据库呢,elasticsearch是面向文档的
如下:对关系型数据库和elasticsearch客观的对比!

关系数据库 非关系数据库
数据库 database 索引 index
表 table type(7版本彻底被弃用)
行 rows document
字段 column field

elasticsearch(集群)中可以包含多个索引(数据库),每个索引中可以包含多个类型(表),每个类型下又包含多个文档(行),每个文档中又包含多个字段(列)。

6. 物理设计

elasticsearch 在后台把每个索引划分成多个分片,每个分片可以在集群中的不同服务器间迁移。
集群的默认名称为 elasticsearch。
在这里插入图片描述
一个集群至少有一个节点,而一个节点就是一个 elasticsearch 进程,节点可以有多个索引默认的,如果你创建索引,那么索引将会有5个分片(primary shard,又称为主分片)构成的,每一个主分片会有一个副本(replica shard,又称赋值分片)
在这里插入图片描述
索引呗分为多个分片,没份分片是一个Lucene 的索引,所以一个elasticsearch索引是由多个Lucene索引组成的。因为elasticsearch使用Lucene作为底层。

二、ES的命令风格

一种软件架构风格,而不是标准,只是提供了一组设计原理和约束条件,它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

基本RESTFUL 命令说明:

method url地址 描述
PUT localhost:9200/索引名称/类型名称/文档id 创建文档(指定文档id)
POST localhost:9200/索引名称/类型名称 创建文档(随机文档id)
POST localhost:9200/索引名称/类型名称/文档id/_update 修改文档
DELETE localhost:9200/索引名称/类型名称/文档id 删除文档
GET localhost:9200/索引名称/类型名称/文档id 查询文档通过文档id
POST localhost:9200/索引名称/类型名称/文档id/_search 查询所有文档
  1. PUT :一般为创建 索引、类型、文档
  2. POST:添加数据,创建索引、类型,查询
  3. DELETE:删除索引、文档
  4. GET:查询

三、新建和删除index索引

  1. 创建索引index
    PUT /weather
    等价于
    curl -X PUT 'localhost:9200/weather'
    服务器返回一个 JSON 对象,里面的acknowledged字段表示操作成功。
    在这里插入图片描述
  2. 然后,发出 DELETE 请求,删除这个 Index。
    DELETE /weather
    等价于
    curl -X DELETE 'localhost:9200/weather'
    在这里插入图片描述

四、分词器使用和学习

elasticsearch的查询,是通过分词器先进行分词,然后再使用倒排索引去匹配查询。

1. 理论学习

分词:即把一段中文或者别的划分为一个个的关键词, 我们在搜索时候, elasticsearch 分词器会把自己的信息进行分词,会把数据库中或者索引库中的数据进行分词,然后进行一个匹配操作默认的中文分词是将每字看成一个词,比如“我爱冯凡利” 会被分为“我”,“爱”,“冯”,“凡”,“利”,这显然是不符合要求的,所以我们需要安装中文分词器 ik 来解决这个问题。

ES默认的分词是英文分词,对中文分词支持的并不好。如果要使用中文,建议使用ik分词器!所以我们就需要安装ik中文分词。

IK提供了两个分词算法:ik_smartik_max_word,其中 ik_mart 为最少切分ik_max_word为最新粒度划分!一会我们测试!

安装在第一篇博客中已经介绍,传送门:elasticsearch学习一:了解 ES,版本之间的对应。安装elasticsearch,kibana,head插件、elasticsearch-ik分词器。

2. 使用kibana测试

  1. ik_mart 为最少切分
    在这里插入图片描述

  2. ik_max_word为最新粒度划分,穷尽词库的可能。
    在这里插入图片描述

  3. 输入超级喜欢冯安晨java
    在这里插入图片描述

  4. 发现问题:冯安晨被分开了,
    这种自己需要的词,需要自己加到我们的分词器的字典中!

ik分词器增加自己的配置!

  1. ik分词器自定义配置,已经单写了一个博客:elasticsearch学习三:elasticsearch-ik分词器的自定义配置 分词内容
    设置完后,再来执行:
    在这里插入图片描述
  2. 以后需要自己配置的分词就可以在自己定义的 dic 文件中进行配置即可!

五、数据操作

1. 创建索引

  1. 创建索引方式1,单纯创建索引
    PUT /索引名
  2. 创建索引方式2,创建索引并添加数据,字段类型系统默认给出
    这种方式会直接创建出索引名、类型、id,还会添家数据```
    PUT /索引名/~类型名~/文档id
    {请求体}

    ```

  3. 案例```
    PUT /test1/type1/1
    {
    "name": "冯安晨",
    "age": 18
    }

    ```
    这样创建完索引、类型、id后,还添加了一个数据。
    在这里插入图片描述

  4. 创建索引方式3,创建索引并指定字段类型
    创建索引,指定类型名称,并指定 `字段(field)类型````
    PUT /test2
    {
    "mappings": {

    "type2": {
      "properties": {
        "name": {
          "type": "text"
        },
        "age": {
          "type": "long"
        },
        "birthday": {
          "type": "date"
        }
      }
    }
    

    }
    }

    ```

在这里插入图片描述

2. 字段类型总结

那么上面的 name 这个字段用不用指定类型呢,毕竟我们关系型数据库是需要指定类型的!!

  • 字符串类型

    text、keyword

  • 数值类型

    long、integer、short、byte、double、float、half float、scaled float

  • 日期类型

    date

  • 布尔值类型

    boolean

  • 二进制类型

    binary

  • 等等。。。

3. 查看规则信息

也就是获取看一下上面命令创建的详细情况

  1. GET 命令
    GET /test1查看索引信息
    如果自己的文档字段没有指定,那么 ES 会给我们默认配置字段类型!就是上面的 test1 索引,没有指定字段类型,所以ES 默认指定类型。
    在这里插入图片描述

4. 系统命令

通过 elasticsearch 命令查看 ES 的各种信息! 通过
GET _cat/
可以获得 ES 的当前很多信息!

  1. GET _cat/indices/?v:查看 索引情况
    在这里插入图片描述
  2. 其他命令。
    在这里插入图片描述

5 添加数据

默认指定数据的类型

PUT /fenganchen/user/1
{
  "name": "冯凡利",
  "age": 18,
  "desc": "一顿操作猛如虎,一看工资2500",
  "tags": ["技术宅", "温暖", "直男"]
}

6. 修改数据

a. PUT修改(不推荐)

像添加一样,进行修改,但是这个修改类似于覆盖,如果缺少一个字段,则消失一个字段

  1. 查看 GET /fenganchen/user/1(下面讲)
    在这里插入图片描述

  2. 修改

    PUT /fenganchen/user/1
    {
      "name": "冯凡利123",
      "age": 18,
      "desc": "一顿操作猛如虎,一看工资2500",
      "tags": ["技术宅", "温暖", "直男"]
    }
    

    _version 代表被修改的次数
    在这里插入图片描述

  3. 查看确认
    GET /fenganchen/user/1
    在这里插入图片描述

b. _update修改(推荐)

  1. 修改
POST fenganchen/user/1/_update
{
  "doc": {
    "name": "冯凡利java"
  }
}

在这里插入图片描述
2. 查看
在这里插入图片描述

7. 删除

7. 简单查询

  1. GET fenganchen/user/1
    在这里插入图片描述
  2. 简单条件查询
GET /fenganchen/user/_search?q=name:冯凡利  (报错,还未找到原因)

GET /fenganchen/user/_search?q=age:18

在这里插入图片描述
在这里插入图片描述

8.复杂查询

  1. 多添加几个数据
PUT /fenganchen/user/2
{
  "name": "张三",
  "age": 17,
  "desc": "法外狂徒张三",
  "tags": ["技术宅", "温暖", "渣男"]
}

PUT /fenganchen/user/3
{
  "name": "李四",
  "age": 30,
  "desc": "mmp 不知怎么形容了",
  "tags": ["靓女", "旅游", "唱歌"]
}
  1. query关键字:查询
    match关键字:匹配,这里的有很多选择,如:match_all:匹配全部,bool:返回布尔值,exists:是否存在等等。```
    GET fenganchen/user/_search
    {
    "query": {

    "match": {
      "name": "冯凡利"
    }
    

    }
    }

    ```

在这里插入图片描述
3. 再添加一个数据,便于查询测试:

PUT /fenganchen/user/4
{
  "name": "冯凡利前端",
  "age": 3,
  "desc": "一顿操作猛如虎,一看工资2500",
  "tags": ["技术宅", "温暖", "直男"]
}
  1. 再次查询:如下图

    hits:包括索引和文档信息、查询结果总数、查询出来具体文档
    max_score:最大分数,这是下面数据中最大的匹配分数值,也是最合适的
    _score:可以通过它来判断谁更加符合结果,每个数据中都有这个属性
    _source:数据对象信息关键字。

在这里插入图片描述

9 过滤结果

不想显示那么多字段,只想显示其中的 namedesc 字段,可以使用 数据对象信息关键字 :_source 来限定显示的字段。

GET fenganchen/user/_search
{
  "query": {
    "match": {
      "name": "冯凡利"
    }
  },
  "_source": ["name", "desc"]
}

在这里插入图片描述
我们之后使用java操作es,所有的方法和对象就是这里面的key:这个key也就是 hits、score等关键字

10. 排序

GET fenganchen/user/_search
{
  "query": {
    "match": {
      "name": "冯凡利"
    }
  },
  "sort": [
    {
      "age": {
        "order": "asc"
      }
    }
  ]
}

在这里插入图片描述

11. 分页查询

GET fenganchen/user/_search
{
  "query": {
    "match": {
      "name": "冯凡利"
    }
  },
  "sort": [
    {
      "age": {
        "order": "desc"
      }
    }
  ],
  "from": 0,
  "size": 1
}

在这里插入图片描述
from: 从第几个数据开始
size:返回多少条数据(单页面的数据)

数据下标还是从0开始,和学的所有数据结构是一样的!
/search/{current}/{pagesize}

12. 布尔查询

  1. must(and) ,所有的条件都要符合,类似于:`where id=1 and name=xxx````
    GET fengfanli/user/_search
    {
    "query": {

    "bool": {
      "must": [
        {
          "match": {
            "name": "冯凡利"
          }
        },
        {
          "match": {
            "age": "18"
          }
        }
      ]
    }
    

    }
    }

    ```

在这里插入图片描述

  1. should(or) ,所有的条件都要符合,类似于:where id=1 orname=xxx```
    GET fenganchen/user/_search
    {
    "query": {

    "bool": {
      "should": [
        {
          "match": {
            "name": "冯凡利"
          }
        },
        {
          "match": {
            "age": "18"
          }
        }
      ]
    }
    

    }
    }

    ```

在这里插入图片描述

  1. ** must_not( not)** ,所有的条件都要符合,类似于:`where id != 1````
    GET fenganchen/user/_search
    {
    "query": {

    "bool": {
      "must_not": [
        {
          "match": {
            "age": 3
          }
        }
      ]
    }
    

    }
    }

    ```

在这里插入图片描述

13. 过滤器

  1. 普通匹配查询
    包含 冯凡利 字符串的都会被查找出来```
    GET fenganchen/user/_search
    {
    "query": {

    "bool": {
      "must": [
        {
          "match": {
            "name": "冯凡利"
          }
        }
      ]
    }
    

    }
    }

    ```

在这里插入图片描述

  1. 加入过滤器,进行过滤
    filter 关键字,对查询的数据进行过滤。

    • gt 大于
    • gte 大于等于
    • lt 小于
    • lte 小于等于
    GET fenganchen/user/_search
    {
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "name": "冯凡利"
              }
            }
          ],
          "filter": {
            "range": {
              "age": {
                "gt": 3
              }
            }
          }
        }
      }
    }
    

    上面的语句 便是对 查询出来的语句 进行过滤,过滤出 age 大于3 的数据

在这里插入图片描述

14. 空格 匹配多个条件

match 关键字 空格
多个条件,使用空格隔开
只要瞒住其中一个结果就可以查出
这个时候可以通过 _score 分值进行基本的判断
下面的查询语句意思:在tags 字段中找到有 男、技术 的数据给查询出来

GET fenganchen/user/_search
{
  "query": {
    "match": {
      "tags": "男 技术"
    }
  }
}

在这里插入图片描述

15. term 精确查询

i. term分析

term 查询 是直接通过倒排索引指定的词条进程精确的查找的!
在这里插入图片描述
关于分词

  • term :直接查询 精确的

  • match :会使用分词器解析!(先分析文档,然后再通过分析进行查询!)

ii. 两个类型 text keyword 细节分析

两个类型 text keyword 不能被分词器使用
text类型 :可以被分词
keyword类型 :不可以被分词

先创建索引,并指定属性规则,如下:

a. 6版本创建索引,指定规则

elasticsearch 6.X 创建索引 必须要指定类型,feng_type 就是索引的类型名称

```json
PUT testdb
{
  "mappings": {
    "feng_type": {
      "properties": {
        "name": {
          "type": "text"
        },
        "desc": {
          "type": "keyword"
        }
      }
    }
  }
}

在这里插入图片描述

b. 7版本创建索引,指定规则

elasticsearch 7.x 创建索引 不用指定类型,因为7版本废弃了类型关键词(这里不再演示,我这里使用的是 6.4.2 版本。)

```json
PUT testdb
{
  "mappings": {
    "properties": {
      "name": {
        "type": "text"
      },
      "desc": {
        "type": "keyword"
      }
    }
  }
}
c. 添加数据

PUT testdb/feng_type/1
{
  "name": "冯凡利java name",
  "desc": "冯凡利java desc"
}

PUT testdb/feng_type/2
{
  "name": "冯凡利java name",
  "desc": "冯凡利java desc2"
}

添加文档 1

在这里插入图片描述
添加文档 2
在这里插入图片描述

d. elasticsearch-head 的Google插件,查看 testdb 索引数据

在这里插入图片描述

e. elasticsearch-head 的Google插件,查看 testdb 映射规则

索引情况,能查看索引的 setting 详情,和 mapperings 映射规则 包括类型、属性情况。
可以看到,name 属性 是 text 类型的,desc 是 keyword 类型的。
在这里插入图片描述

f. 默认分词器测试:keyword

KeywordAnalyzer 把整个输入作为一个单独词汇单元,方便特殊类型的文本进行索引和检索。针对邮政编码,地址等文本信息使用关键词分词器进行索引项建立非常方便。

使用默认的 keyword 分词器进行分词,(说一下,ik分词器是中文分词器)这里看的出来没有被分析
在这里插入图片描述

g. 默认分词器测试:standard

英文的处理能力同于StopAnalyzer,支持中文采用的方法为单字切分。他会将词汇单元转换成小写形式,并去除停用词和标点符号。

使用默认的 standard 分词器进行分词,,这里看的出来被分析了
在这里插入图片描述

h. term 精确查找 text类型

在这里插入图片描述

i. term 精确查找 keyword 类型

在这里插入图片描述
在这里插入图片描述

j. 对h和i的测试进行 总结

testdb索引中的 :
name字段为 text类型
desc字段为 keyword类型

但是 term 分别对其 精确查找时,却发现:

  1. 查找text类型的name字段时时,只要包含就好,也就是text类型可以被分词器解释
  2. 查找keyword 类型的 desc 字段时,必须全包含才行,也就是keyword类型把整个输入作为一个单独词汇单元 去匹配被分词器解释。

16. 多个词精确拼配

a. 添加多数

PUT testdb/feng_type/3
{
  "t1": "22",
  "t2": "2020-4-6"
}

PUT testdb/feng_type/4
{
  "t1": "33",
  "t2": "2020-4-7"
}

在这里插入图片描述
在这里插入图片描述

b. 查看elasticsearch-head 的Google插件,查看 testdb 索引数据和映射规则。

  1. 索引数据
    在这里插入图片描述
  2. 映射规则
    在这里插入图片描述

c. term 精确查询

在这里插入图片描述

17. 高亮显示

1、 高亮关键字:highlight

GET fenganchen/user/_search
{
  "query": {
    "match": {
      "name": "冯凡利"
    }
  },
  "highlight": {
    "fields": {
      "name": {}
    }
  }
}

在这里插入图片描述

2、 自定义搜索高亮

GET fenganchen/user/_search
{
  "query": {
    "match": {
      "name": "冯凡利"
    }
  },
  "highlight": {
    "pre_tags": "<p class='key style='color:red'>",
    "post_tags": "</p>", 
    "fields": {
      "name": {}
    }
  }
}

在这里插入图片描述

这些 mysql也可以做,只是mysql效率比较低

  • 匹配
  • 按照条件匹配
  • 精确匹配
  • 区间范围匹配
  • 多条件查询
  • 高亮查询
相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
24天前
|
存储 监控 安全
|
2月前
|
自然语言处理 机器人 Python
ChatGPT使用学习:ChatPaper安装到测试详细教程(一文包会)
ChatPaper是一个基于文本生成技术的智能研究论文工具,能够根据用户输入进行智能回复和互动。它支持快速下载、阅读论文,并通过分析论文的关键信息帮助用户判断是否需要深入了解。用户可以通过命令行或网页界面操作,进行论文搜索、下载、总结等。
51 1
ChatGPT使用学习:ChatPaper安装到测试详细教程(一文包会)
|
26天前
|
前端开发 JavaScript 安全
学习如何为 React 组件编写测试:
学习如何为 React 组件编写测试:
36 2
|
27天前
|
编解码 安全 Linux
网络空间安全之一个WH的超前沿全栈技术深入学习之路(10-2):保姆级别教会你如何搭建白帽黑客渗透测试系统环境Kali——Liinux-Debian:就怕你学成黑客啦!)作者——LJS
保姆级别教会你如何搭建白帽黑客渗透测试系统环境Kali以及常见的报错及对应解决方案、常用Kali功能简便化以及详解如何具体实现
|
2月前
|
分布式计算 Hadoop 大数据
大数据体系知识学习(一):PySpark和Hadoop环境的搭建与测试
这篇文章是关于大数据体系知识学习的,主要介绍了Apache Spark的基本概念、特点、组件,以及如何安装配置Java、PySpark和Hadoop环境。文章还提供了详细的安装步骤和测试代码,帮助读者搭建和测试大数据环境。
61 1
|
2月前
|
测试技术 Python
自动化测试项目学习笔记(二):学习各种setup、tearDown、断言方法
本文主要介绍了自动化测试中setup、teardown、断言方法的使用,以及unittest框架中setUp、tearDown、setUpClass和tearDownClass的区别和应用。
65 0
自动化测试项目学习笔记(二):学习各种setup、tearDown、断言方法
|
27天前
|
人工智能 安全 Linux
网络空间安全之一个WH的超前沿全栈技术深入学习之路(4-2):渗透测试行业术语扫盲完结:就怕你学成黑客啦!)作者——LJS
网络空间安全之一个WH的超前沿全栈技术深入学习之路(4-2):渗透测试行业术语扫盲完结:就怕你学成黑客啦!)作者——LJS
|
27天前
|
安全 大数据 Linux
网络空间安全之一个WH的超前沿全栈技术深入学习之路(3-2):渗透测试行业术语扫盲)作者——LJS
网络空间安全之一个WH的超前沿全栈技术深入学习之路(3-2):渗透测试行业术语扫盲)作者——LJS
|
27天前
|
SQL 安全 网络协议
网络空间安全之一个WH的超前沿全栈技术深入学习之路(1-2):渗透测试行业术语扫盲)作者——LJS
网络空间安全之一个WH的超前沿全栈技术深入学习之路(1-2):渗透测试行业术语扫盲)作者——LJS
|
2月前
|
监控 Java Maven
springboot学习二:springboot 初创建 web 项目、修改banner、热部署插件、切换运行环境、springboot参数配置,打包项目并测试成功
这篇文章介绍了如何快速创建Spring Boot项目,包括项目的初始化、结构、打包部署、修改启动Banner、热部署、环境切换和参数配置等基础操作。
148 0
下一篇
无影云桌面