当前位置: 首页 > news >正文

ES(Elasticsearch) 基本概念(一)

Elasticsearch作为当前最流行的开源搜索和分析引擎,广泛应用于日志分析、全文搜索、业务智能等领域。Elasticsearch是一个基于 Apache Lucene 构建的分布式搜索和分析引擎、可扩展数据存储和矢量数据库。它针对生产级工作负载的速度和相关性进行了优化。使用 Elasticsearch 可以近乎实时地搜索、索引、存储和分析各种类型和大小的数据。Kibana是 Elasticsearch 的图形用户界面。它是一款强大的工具,可用于可视化和分析数据,以及管理和监控 Elastic Stack。本文将带你系统学习Elasticsearch的核心概念和基本用法。

一、Elasticsearch基础概念

在开始实际操作前,我们需要了解几个核心概念:

  1. 文档(Document)
    1. ES是面向文档的,文档是所有可搜索数据的最小单元
    2. 文档会被序列化成JSON格式存储
    3. 每个文档都有唯一ID,可自定义或自动生成
    4. 支持数组和嵌套结构
  2. 索引(Index)
    1. 相当于MySQL中的数据库
    2. 名称必须全部小写
    3. 包含mapping(定义字段类型)和setting(定义数据分布)
  3. 节点(Node)与分片(Shard)
    1. 节点:是 一个ES实例,本质是一个Java进程
      1. Master Eligible节点:参与选主,管理集群状态
      2. Data节点:存储数据
      3. Coordinating节点:接收客户端请求
      4. 节点的名称可以通过配置文件配置,或者在启动的时候使用-E node.name=ropledata指定,默认是随机分配的。建议咱们自己指定,因为节点名称对于管理目的很重要,咱们可以通过节点名称确定网络中的哪些服务器对应于ES集群中的哪些节点;
    2. 分片:将索引水平拆分为多个部分
      1. 主分片数在创建索引时指定,后续不能修改
      2. 副本分片提供高可用性,可动态调整数量
  4. 类型:就相当于MySql里的表,我们知道MySql里一个库下可以有很多表,最原始的时候ES也是这样,一个索引下可以有很多类型,但是从6.0版本开始,type已经被逐渐废弃,但是这时候一个索引仍然可以设置多个类型,一直到7.0版本开始,一个索引就只能创建一个类型了(_doc)。 Elasticsearch7 去掉 tpye 概念ES7.x 版本:URL 中的 type 参数为可选。 ES8.x 版本:不⽀持 URL 中的 type 参数

注意:虽然在实际存储上,文档存在于某个索引里,但是文档必须被赋予一个索引下的

二、什么是倒排索引?

倒排索引(Inverted Index)是搜索引擎最核心的数据结构,也是Elasticsearch实现高效全文搜索的基础。它与我们熟悉的传统"正排索引"形成鲜明对比:

  • 正排索引(正向索引):文档文档(Document)
    • ES是面向文档的,文档是所有可搜索数据的最小单元
    • 文档会被序列化成JSON格式存储
    • 每个文档都有唯一ID,可自定义或自动生成
    • 支持数组和嵌套结构
  • 索引(Index)
    • 相当于MySQL中的数据库
    • 名称必须全部小写
    • 包含mapping(定义字段类型)和setting(定义数据分布)
  • 节点(Node)与分片(Shard)
    • 节点:一个ES实例,本质是一个Java进程
      • Master Eligible节点:参与选主,管理集群状态
      • Data节点:存储数据
      • Coordinating节点:接收客户端请求
    • 分片:将索引水平拆分为多个部分
      • 主分片数在创建索引时指定,后续不能修改
      • 副本分片提供高可用性,可动态调整数量
  • → 包含的词
    • 类似书籍的目录,通过章节找内容
    • 如:文档1包含"大话"、"西游"
  • 倒排索引(反向索引):词 → 出现的文档
    • 类似书籍的索引页,通过关键词找章节
    • 如:"西游" → 文档1、文档2、文档3...

三、倒排索引的构建过程

3.1 原始数据示例

以电影片名为例:

文档ID

电影名称

1

大话西游

2

大话西游外传

3

解析大话西游

4

西游降魔外传

5

梦幻西游独家解析

3.2 分词处理

中文需要先进行分词(使用分词器将句子拆分为词语):

  • "大话西游" → ["大话", "西游"]
  • "大话西游外传" → ["大话", "西游", "外传"]
  • "解析大话西游" → ["解析", "大话", "西游"]
  • "西游降魔外传" → ["西游", "降魔", "外传"]
  • "梦幻西游独家解析" → ["梦幻", "西游", "独家", "解析"]

3.3 构建倒排列表

对分词结果进行反向记录:

词项

文档ID列表(Posting List)

其他信息(如词频、位置等)

西游

1,2,3,4,5

在1中出现1次,在2中出现1次...

大话

1,2,3

在1中出现1次,在2中出现1次...

外传

2,4

在2中出现1次,在4中出现1次...

解析

3,5

在3中出现1次,在5中出现1次...

降魔

4

在4中出现1次

梦幻

5

在5中出现1次

独家

5

在5中出现1次

三、倒排索引的搜索过程

3.1 搜索示例:查询"独家大话西游"

  1. 查询分词
    1. "独家大话西游" → ["独家", "大话", "西游"]
  2. 查找倒排列表
    1. "独家" → 文档5
    2. "大话" → 文档1,2,3
    3. "西游" → 文档1,2,3,4,5
  3. 合并结果
    1. 文档1:包含"大话"、"西游"
    2. 文档2:包含"大话"、"西游"
    3. 文档3:包含"大话"、"西游"
    4. 文档5:包含"独家"、"西游"
    5. 文档4:只包含"西游"

相关性评分(简化版)

评分公式:

得分 = 命中词数 / 文档总词数

    1. 文档1:命中2词("大话"、"西游"),总词数2 → 2/2=1.0

    2. 文档2:命中2词,总词数3 → 2/3≈0.67

    3. 文档3:命中2词,总词数3 → 2/3≈0.67

    4. 文档5:命中2词("独家"、"西游"),总词数4 → 2/4=0.5

    5. 文档4:命中1词("西游"),总词数3 → 1/3≈0.33

结果排序

1. 大话西游 (1.0)
2. 大话西游外传 (0.67)
3. 解析大话西游 (0.67)
4. 梦幻西游独家解析 (0.5)
5. 西游降魔外传 (0.33)

基础操作

索引管理 

// 创建索引
PUT /ropledata
{"settings": {"number_of_shards": "2","number_of_replicas": "3"}
}// 删除索引
DELETE /ropledata// 修改副本数
PUT ropledata/_settings
{"number_of_replicas": "2"
}

什么是映射?

映射(Mapping)是ElasticSearch中用于定义文档及其包含字段如何存储和索引的机制。它相当于关系型数据库中的表结构定义,决定了:

  1. 哪些字段应该被当作全文检索字段
  2. 哪些字段包含数字、日期或地理位置信息
  3. 日期值的格式
  4. 自定义规则来控制动态添加字段的映射

映射的核心作用

  1. 字段类型定义:指定每个字段的数据类型(如text、keyword、integer等)
  2. 索引控制:决定字段是否被索引(可搜索)
  3. 分析器配置:指定文本字段使用的分词器
  4. 格式设置:如日期字段的格式
  5. 多字段支持:一个字段可以有不同的索引方式

映射类型

1. 显式映射

级属性映射 

用户明确定义字段的映射规则:

PUT /my-index
{"mappings": {"properties": {"age":    { "type": "integer" },  "email":  { "type": "keyword" },"name":   { "type": "text" }}}
}

多级属性映射 

PUT /my-index
{"mappings": {"properties": {"age": { "type": "integer" },"email": { "type": "keyword" },"name": { "type": "text" },"address": {"type": "nested","properties": {"street": { "type": "text" },"city": { "type": "keyword" },"zipcode": { "type": "keyword" },"coordinates": {"type": "object","properties": {"lat": { "type": "float" },"lon": { "type": "float" }}}}},"skills": {"type": "nested","properties": {"name": { "type": "keyword" },"level": { "type": "integer" },"certifications": {"type": "nested","properties": {"name": { "type": "text" },"year": { "type": "short" }}}}},"employment_history": {"type": "nested","properties": {"company": { "type": "keyword" },"position": { "type": "text" },"duration_months": { "type": "integer" }}}}}
}

这个映射定义包含:

  1. 基本字段:age(integer), email(keyword), name(text)
  2. 嵌套地址对象:包含街道(text)、城市(keyword)、邮编(keyword)和坐标对象
  3. 嵌套技能数组:包含技能名(keyword)、等级(integer)和嵌套的认证数组
  4. 嵌套工作经历数组:包含公司(keyword)、职位(text)和持续时间(integer)

所有嵌套关系都使用 "type": "nested" 来确保数组中的对象被独立索引和查询。

2. 动态映射

当索引新文档时,ES会自动检测并添加新字段:

PUT /my-index/_doc/1
{"age": 25,"email": "user@example.com","name": "John Doe"
}

ES会自动推断:

age → long

email → keyword

name → text

常用字段类型

类型

说明

text

全文检索字段,会被分词

keyword

精确值字段,不分析,用于过滤、排序和聚合

long/integer

长整型/整型数值

double/float

双精度/单精度浮点数

date

日期类型,可指定格式

boolean

布尔值

object

JSON对象

nested

嵌套对象,保持数组中对象的独立性

geo_point

经纬度坐标

映射操作示例

查看映射

GET /my-index/_mapping

添加新字段映射

PUT /my-index/_mapping
{"properties": {"employee-id": {"type": "keyword","index": false}}
}

更新映射注意事项

重要:已存在字段的映射类型不能直接修改,必须:

  1. 创建新索引并定义新映射
  2. 使用_reindex API迁移数据
POST _reindex
{"source": { "index": "old-index" },"dest": { "index": "new-index" }
}

映射参数详解

常用参数

  1. index:是否索引该字段(true/false)
  2. analyzer:指定文本分析器
  3. search_analyzer:指定搜索时分析器
  4. format:日期格式(如"yyyy-MM-dd")
  5. copy_to:将字段值复制到目标字段
  6. fields:多字段特性,允许一个字段有多种索引方式

多字段示例

{"mappings": {"properties": {"city": {"type": "text","fields": {"raw": { "type": "keyword"}}}}}
}

这样city可以用于全文搜索,city.raw可用于精确匹配和聚合。

索引数据

  1. 预先定义映射:生产环境建议预先定义映射,避免动态映射的不确定性
  2. 合理使用keyword:不需要分词的字段应设为keyword类型
  3. 控制动态映射:可通过dynamic参数控制(true/false/strict)
  4. 避免频繁修改:映射特别是字段类型不宜频繁变更
  5. 使用别名:便于重建索引时无缝切换映射是ElasticSearch高效工作的基础,合理的映射设计能显著提升搜索性能和结果的准确性。

一、数据插入操作

1. 不指定文档ID插入

Elasticsearch 会自动生成唯一ID

POST /ropledata/_doc/
{"id":1,"name":"且听_风吟","page":"https://ropledata.blog.csdn.net","say":"欢迎点赞,收藏,关注,一起学习"
}

2. 指定文档ID插入

适用于需要自定义ID的场景

POST /ropledata/_doc/101
{"id":1,"name":"且听_风吟","page":"https://ropledata.blog.csdn.net","say":"欢迎点赞,收藏,关注,一起学习"
}

二、数据删除操作

删除指定ID的文档:

DELETE /ropledata/_doc/101

三、数据更新操作

1. 全局更新(覆盖更新)

会完全替换原有文档内容

PUT /ropledata/_doc/101
{"id":1,"name":"且听_风吟","page":"https://ropledata.blog.csdn.net","say":"再次欢迎点赞,收藏,关注,一起学习"
}

2. 局部更新

只更新指定字段,性能优于全局更新

POST /ropledata/_update/101
{"doc": {"say":"奥力给"}
}

四、数据查询操作

1. 基础查询(默认返回10条)

GET /ropledata/_search

2. 带条件的全局查询

POST /ropledata/_search
{"query": {"match_all": {}},"sort": [{"id": {"order": "asc"}}]
}

五、索引重建操作

POST _reindex
{"source": { "index": "twitter" },"dest": { "index": "new_twitter" }
}

关键知识点总结

  1. 插入数据
    1. 不指定ID时ES自动生成
    2. 指定ID适用于业务关联场景
  2. 更新机制
    1. ES文档不可变,更新实质是新版本覆盖旧版本
    2. 局部更新(_update)比全局更新(PUT)性能更好
  3. 查询特点
    1. 默认返回10条结果
    2. 可通过sort参数控制排序
    3. match_all查询全部文档
  4. 版本兼容性
    1. 本文示例适用于Elasticsearch 7.x版本
    2. 6.x及以下版本语法可能有差异
  5. 性能建议
    1. 频繁更新的字段考虑单独索引
    2. 大文档更新优先使用局部更新

提示:在实际开发中,建议结合业务场景选择合适的操作方式,批量操作(Bulk API)能显著提高大批量数据处理的效率。

http://www.xdnf.cn/news/549397.html

相关文章:

  • 【Linux】初见,基础指令(续)
  • Linux第十一讲:信号
  • 构建自动收集并总结互联网热门话题的网站
  • 进程间通信(IPC)常用方式对比
  • 当PLC遇上电焊机器人:EtherCAT转CANopen上演工业级“语言翻译官”
  • DP2 跳台阶【牛客网】
  • [面试精选] 0001. 两数之和
  • 人工智能的“歧视”:“她数据”在算法运行中隐形
  • C46-二维数组与指针的总结
  • VUE3 中的 ResizeObserver 警告彻底解决方案
  • C#:多线程Task使用
  • c++使用protocol buffers
  • JS实现古诗竖排从右至左
  • 谈谈jvm的调优思路
  • c++学习方向选择说明
  • [软件工程]第二章题目汇总
  • MySQL 8.0窗口函数详解
  • 48、c# 中 IList 接⼝与List的区别是什么?
  • Gin--Blog项目-flags文件解析
  • RK3576 Android 14.0 SDK开发指南(第一集)
  • 丝杆升降机在锂电行业的自动化应用有什么?
  • Unity-编辑器扩展
  • 2025年护网行动蓝队防御全解析:构建智能动态防御体系
  • Raft算法学习(1)博士论文大纲
  • Go学习教程(附电子书资料)
  • 桥梁凝冰在线监测装置:科技守护道路安全的新防线
  • Python入门手册:Python简介,什么是Python
  • C++之fmt库介绍和使用(2)
  • GPS模块_亿佰特E108-GN04D_u-center2调试
  • Linux:面试题