Elasticsearch7 自学记录一 基础原理和简单查询

本文档介绍了Elasticsearch7的基础概念、分布式索引原理及其基本使用方法,包括索引、文档的操作及简单查询。此外还探讨了TF-IDF得分规则和倒排索引机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Elasticsearch7 自学记录一 基础原理和简单查询
Elasticsearch7 自学记录二 进阶查询




前言

本人在慕课网学习elasticsearch7的学习笔记总结,并记录一些自己的理解。


一、elasticsearch7搜索的本质及原理

先从es的名词开始了解这个搜索引擎

1.1结构名词

名称解释
index (索引)索引相当于库的概念,存放文档
type (类型)es7这个已经没有了,所以不用管了
Document (文档)相当于一条记录,在关系型数据库中类似一行记录,一个数据对象
Field (字段)在关系型数据库中属于列的概念,数据对象的字段
Mapping (映射)数据对象的结构

1.2分布式索引原理名词

节点(node):elasticsearch 的 jar 包可以部署在多台服务器上形成多节点的集群,当然也可以在单台机器上部署多个节点,因为有分片的概念就算是单节点,也属于分布式。

分片 (shard):分片就是将一个索引分成不同部分,如果是多节点的话会平均分布在不同节点上,当然单个节点也是可以设置多分片的。分片数越多自然会损耗查询的性能,我认为单节点的es,分片值设置为1即可,分片就是为了集群节点的负载均衡,单节点就没这个必要了,且索引的分片数量是不能更改的。
看了官网也没很清楚的指出集群下分片的数量应该怎么设置,网上的答案也不尽相同,大家可以留言讨论。

副本(replica):即每个分片的备份,备份的作用当然就是为了恢复数据使用的,副本数量会影响索引的写入性能,根据我自己的观察副本数量最多可设置 = 节点数量-1
所以当只有单个节点的时候,创建索引需指定副本数为0,不然索引的状态会是yellow告警状态,如图:
索引状态
在kibana中可以看到索引的状态分为三种:red (有分片失效) yellow(副本失效) green(健康)
单节点3个分片的图示:
单节点三分片
两个节点 3分片 1个副本图示:
可以看到的是某个副本不会和自己的主分片处于同一个节点,所以我们可以得出结论 最大副本数量=节点数-1
双节点3分片1副本
三节点 3分片 1副本 图示:
分配的情况怪怪的,不过我就不去理解内部具体的分配规则了
三节点 3分片 1副本
三节点 3分片 2副本
可以看到的是这边还是满足副本不会和主分片
三节点 3分片 2副本

双节点 2分片2副本 插入文档时图示:
可以看到文档由主节点的P1分片通知,并插入到node3节点的P0分片,P0分片的两个副本R0 会相应的插入数据。
双节点 2分片2副本 插入文档

查询文档时图示:
可以看到es 的分布式工作能力是很强的,只要一个分片就可以知道所有分片的数据。
查询文档时图示

1.3其他名词

分词:
通俗来说就是把一句短语 或者 一句完整的句子 分成一个个单词,先简易的介绍一下es 内置的几种分词器,知道了分词的概念才能了解索引倒排,后面的文章使用例子会使用到ik中文分词器,并自定义分词器。

(1)standard analyzer :标准分词器 作为默认分词器,按词切分,支持多种语言,会删除符号, 会将英文全部转成小写,示例如图

例:POST _analyze
{
  "analyzer": "standard",
  "text": "The programmer's holiday is 1024!"
}

text 中的句子经过标准分词器分词后为:[ the, programmer’s, holiday,is,1024]

(2)language analyzers :指定的语言分词器,例如英文分词器, 会过滤停用词 如 the,is ,an 等,会提取词干,会删除符号, 会将英文全部转成小写

GET /_analyze
{
  "analyzer": "english",
  "text": "The programmer's holiday is 1024!"
}

分词后为:[programm,holidai,1024]

(3)simple analyzer :简单分词器 按照非字母切分,简单分词器在遇到不是字母的字符时将文本分解为术语

GET /_analyze
{
  "analyzer": "simple",
  "text": "The programmer's holiday is 1024!"
}

分词后为:[the,programmer,s,holiday,is]

(4)whitespace analyzer :空格分词器 简单的按空格进行划分
(5)keyword analyzer : 不进行任务处理

倒排索引: 指的是将单词或记录作为索引,将文档ID作为记录,这样便可以方便地通过单词或记录查找到其所在的文档。
例如有0~4 这5个文档,包含两个字段 id 和 title
在这里插入图片描述

然后对文档中数据进行分词,得到词条。对词条进行编号,以词条创建索引。然后记录下包含该词条的所有文档编号(及其它信息)
在这里插入图片描述
搜索的过程:

当用户输入任意的词条时,首先对用户输入的数据进行分词,得到用户要搜索的所有词条,然后拿着这些词条去倒排索引列表中进行匹配。找到这些词条就能找到包含这些词条的所有文档的编号。
然后根据这些编号去文档列表中找到文档

TF-IDF: 这个是查询后文档得分的重要依据,先理解词的意思,得分规则会在后面详细说明

  1. TF: 词频 这个document文档包含了多少个这个词,包含越多表明越相关
  2. DF:文档频率 包含该词的文档总数目
  3. IDF: DF取反 1/DF

二、基础使用示例

这边先简单的介绍一下一些简单操作,后面的章节会插入大量数据,用来学习复杂查询和文档的得分规则。

1.索引基础操作

2.1.1 非结构化方式新建索引
其中shards 为主分片数量,replicas为副本数量数量,索引创建后副本数量可以修改,主分片数量不可修改。

PUT /employee
{
   "settings": {
    "number_of_shards": 1,
    "number_of_replicas": 1
  }
}

2.1.2 结构化的方式创建索引
结构化方式创建索引是更标准的方式,mappings 是映射关系,指定字段名称和字段类型,以及分词器等,后面会有更多的例子。

PUT /employee
{
  "settings": {
    "number_of_shards": 1,
    "number_of_replicas": 1
  },
  "mappings": {
    "properties": {
      "name":{"type": "text"},
      "age":{"type": "integer"}
    }
  }
}

2.1.3 删除索引

DELETE /employee

2.1.4 查询索引信息

GET /employee

2.文档基础操作

2.2.1 创建或更新文档

可以是创建文档,或者更新文档,当索引不存在时则以非结构化方式新建索引,并插入文档。
若文档存在作为更新时,这个为全量更新的方法,入参中没有的字段,也会删除文档中相应的字段数据。

PUT /employee/_doc/1
{
  "name":"凯杰2",
  "age":30
}

2.2.2 更新文档的指定字段的数据

POST /employee/_doc/1
{
  "age":24
}

2.2.3 强制指定创建文档,若已存在,则失败

创建文档id为4的文档,若id 已存在不会进行更新操作,会报错,这是和上面put 操作的区别。

POST /employee/_create/1
{
  "name":"兄长2",
  "age":27
}

2.2.4 不指定id 创建文档(新增数据)
系统会自动分配一个文档id

POST /employee/_doc
{
  "name":"兄长2",
  "age":27
}

2.2.5 更新指定字段数据
只更新语句中涉及的字段

POST /employee/_doc/4
{
  "age":24
}

2.2.6 根据文档id 删除文档

DELETE /employee/_doc/2

3.基础查询操作

3.1.1 查询全部文档

#查询全部文档
GET /employee/_search

或者

#不带条件查询所有记录
GET /employee/_search
{
  "query": {
    "match_all": {}
  }
}

如图所示:
在这里插入图片描述
其中有几个字段做一下简单的说明,took 为查询响应的毫秒数,timed_out 查询是否超时标志位。shards 为分片信息
max_score 为文档得分的最高分,在下一个章节会比较全面的介绍复杂查询,以及得分规则这块。hits 查询出来的文档集合。

3.1.2 分页查询
其中 from 为从第几条开始查询 ,size为每页多少条

#分页查询
GET /employee/_search
{
  "query": {
    "match_all": {}
  },
  "from": 0,
  "size": 100
}

3.1.3 带关键字条件的查询—匹配查询(match)

match查询时会默认将查询语句中的短语’兄弟‘进行分词,因为没有指定所以会使用默认的标准分词器,分为“兄”,“弟” 两个词再进行查询,因为文档插入时,根据倒排索引,name字段也进行过分词了,所以包含兄或者弟的都会被命中。

GET /employee/_search
{
  "query": {
    "match": {
      "name": "兄弟"
    }
  }
}

如图所示:
在这里插入图片描述

3.1.4 带排序

这边以age 字段进行排序,值得注意的是 sort是对查询后做的,不属于查询和过滤的条件,因此在query查询对象外面。

GET /employee/_search
{
  "query": {
    "match": {
      "name": "兄长"
    }
  },
  "sort":[
      {"age":"asc"}
    ]
}

3.1.5 带filter
先介绍两个关键字

bool 查询:bool 组合查询是学习高级查询所必须的,bool 查询里面可以包含多种条件,例如:must 则 must 里面的查询条件必须成立,结果为ture,must_not 则相反,必须为flase, should 则是不需要全部成立,成立一个即可,filter 为过滤。

term 词条匹配 :类似于上面的match 查询,但是和它的区别是查询时不会查将查询条件进行分词。

使用filter 文档不参于评分。
所有的查询都会影响到文档的评分及排名。如果我们需要在查询结果中进行过滤,并且不希望过滤条件影响评分,那么就不要把过滤条件作为查询条件来用。而是使用filter方式:

GET /employee/_search
{
  "query": {
    "bool": {
      "filter": [
        {"term": {
          "age": "30"
        }}
      ]
    }
  }
}

如图所示:我们可以看到有个文档命中了,却没有得分。
在这里插入图片描述

我们在bool 中加入must 再试试看

GET /employee/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "name": "凯"
          }
        }
      ], 
      "filter": [
        {"term": {
          "age": "30"
        }}
      ]
    }
  }
}

查询结果如图所示:可以得出结论的是filter 里面的过滤条件不会影响文档的得分。
在这里插入图片描述

3.1.6 带聚合

聚合可以让我们极其方便的实现对数据的统计、分析。例如:

  • 三月份什么汽车品牌的销量最好
  • 某汽车品牌各个价格区间的销量
GET /employee/_search
{
  "query": {
    "match": {
      "name": "兄长"
    }
  },
  "sort":[
      {"age":"asc"}
  ],
  "aggs": {
    "group_by_age": {
      "terms": {
        "field": "age"
      }
    }
  }
}

3.1.7 使用analyze api 查看分词状态

查看某个索引的某个字段,是如何对短语进行分词的。

GET /movie/_analyze
{
  "field": "name",
  "text": "Eating an apple a day & keeps the doctor away"
}

如图所示: 可以看到这是标准分词器分词后的结果
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值