Elasticsearch 教程:从介绍到入门 – wiki基地


Elasticsearch 教程:从介绍到入门——深入理解核心概念与实践操作

引言:大数据时代的搜索引擎与分析引擎

在当今这个数据爆炸的时代,如何高效地存储、搜索和分析海量数据成为了各行各业面临的巨大挑战。传统的关系型数据库在处理全文搜索和实时分析时往往显得力不从心。正是在这样的背景下,以 Elasticsearch 为代表的分布式搜索引擎和分析引擎应运而生,并迅速成为处理大规模非结构化和半结构化数据的事实标准。

Elasticsearch 是一个开源的、基于 Lucene 的分布式、RESTful 风格的搜索和分析引擎。它以其卓越的速度、可伸缩性和强大的全文搜索能力而闻名。无论是构建电商网站的商品搜索、分析服务器日志、监控应用性能指标,还是实现企业内部文档检索,Elasticsearch 都能提供高效可靠的解决方案。

本篇文章将带领读者从零开始,逐步了解 Elasticsearch 的核心概念,理解它的工作原理,并通过实际操作掌握基本的增删改查及搜索功能。无论你是开发者、运维工程师还是数据分析师,希望本文都能为你打开 Elasticsearch 的大门。

第一章:初识 Elasticsearch——它是什么?为什么选择它?

1.1 Elasticsearch 的定位与核心特性

Elasticsearch 不仅仅是一个搜索引擎,它更是一个多功能的分布式数据存储和分析平台。它的核心定位可以概括为:

  • 分布式 (Distributed): 数据分散存储在多个节点上,天然支持水平扩展,能够处理海量数据并提供高可用性。
  • RESTful 风格 (RESTful API): 提供基于 HTTP 的 RESTful API,使得与 Elasticsearch 的交互变得简单直观,可以使用几乎任何编程语言进行操作。
  • 搜索引擎 (Search Engine): 基于 Lucene 构建,提供强大的全文搜索能力,包括模糊匹配、相关性排序、高亮显示等。
  • 分析引擎 (Analytics Engine): 支持复杂的聚合(Aggregations)操作,可以在毫秒级别对海量数据进行统计、分组和计算,实现实时的数据分析和可视化。
  • 实时性 (Near Real-time): 数据写入后,通常在很短的时间(默认为 1 秒)内即可被搜索到。
  • 高可用性 (High Availability): 通过副分片(Replica Shards)机制,即使部分节点发生故障,集群依然能够正常工作。

1.2 Elasticsearch 的流行与生态系统

Elasticsearch 之所以如此流行,很大程度上归功于其围绕着它构建的强大生态系统,最著名的就是 ELK Stack(现在通常称为 Elastic Stack):

  • E – Elasticsearch: 核心引擎,用于存储、搜索和分析数据。
  • L – Logstash: 数据收集、处理和转换管道,可以将各种来源的数据(如日志文件、数据库、消息队列等)采集、过滤后输送到 Elasticsearch。
  • K – Kibana: 数据可视化和管理工具,提供直观的界面来探索 Elasticsearch 中的数据、构建仪表板、执行搜索、管理集群等。

近年来,Elastic Stack 又加入了 Beats(轻量级数据采集器,如 Filebeat, Metricbeat 等),形成了更加完善的数据处理链路。这个强大的组合使得 Elasticsearch 在日志分析、监控和数据分析领域占据了主导地位。

1.3 为什么选择 Elasticsearch?

与传统数据库或其他数据存储方案相比,Elasticsearch 在特定场景下具有明显优势:

  • 全文搜索性能卓越: 专为全文搜索设计,在搜索速度和相关性方面远超传统数据库。
  • 处理海量数据能力强: 分布式架构使得它可以轻松扩展到数百台服务器,处理 PB 级别的数据。
  • 实时性高: 数据写入后立即可搜,适用于需要快速响应的场景。
  • 易于使用和集成: RESTful API 降低了开发门槛,与各种语言和工具集成都很方便。
  • 强大的分析功能: 内置的聚合框架使得复杂的数据分析变得简单高效。
  • 活跃的社区和丰富的文档: 遇到问题容易找到解决方案和学习资源。

当然,Elasticsearch 也不是万能的,它通常不适合作为事务性数据库使用,也不强制要求严格的数据模式(Schema)。但在需要快速搜索和分析大量文本和时序数据时,Elasticsearch 无疑是首选。

第二章:掌握核心概念——构建你的 Elasticsearch 世界观

理解 Elasticsearch 的核心概念是迈向掌握它的关键第一步。虽然它 borrows 了一些传统数据库的术语(如“索引”、“文档”),但它们的含义和工作方式有着显著区别。

2.1 文档 (Document)

  • 定义: Elasticsearch 中最基本的数据单元。一个文档就像数据库中的一行记录,但它更加灵活,是一个 JSON 对象。
  • 特点:

    • 无模式 (Schema-less) 或动态模式 (Dynamic Mapping):你不需要提前定义所有字段的类型,Elasticsearch 会在你索引第一个文档时尝试动态地猜测字段类型。当然,为了精确控制数据类型和索引行为,通常推荐使用显式映射 (Explicit Mapping)。
    • JSON 格式:所有数据都存储为 JSON 格式。
    • 唯一标识:每个文档在一个索引内都有一个唯一的 _id。你可以指定 _id,或者让 Elasticsearch 自动生成。
  • 类比: 类似于关系型数据库中的一行数据,但更加灵活。

2.2 索引 (Index)

  • 定义: 一个相关的文档集合。索引是 Elasticsearch 中组织数据的逻辑空间。
  • 特点:

    • 命名:每个索引都有一个唯一的名称(必须小写)。
    • 搜索范围:搜索是在一个或多个索引上进行的。
    • 分片:一个索引可以被分成多个分片 (Shards),分布在集群的不同节点上。
    • 映射 (Mapping):定义了索引中的文档及其字段如何存储和索引,包括字段的数据类型(字符串、数字、日期等)以及如何分析文本字段。虽然字段类型可以动态猜测,但显式定义映射是最佳实践。
  • 类比: 类似于关系型数据库中的一个数据库 (Database) 或一个表 (Table),但更偏向于一个逻辑分组和物理存储的单位。

2.3 类型 (Type) – 注意已弃用

  • 历史角色: 在 Elasticsearch 6.x 及之前的版本中,一个索引可以包含多个类型(Type),类似于数据库表中的概念。文档通过 _type 字段进行区分。
  • 弃用原因: 由于同一索引下的不同类型共享物理存储和分词器设置,但在逻辑上可能差异很大,导致了一些问题(例如,同一字段名在不同类型下有不同含义时)。为了简化模型,Elasticsearch 在 7.x 版本开始弃用 Type,并在 8.x 版本中完全移除。
  • 当前状态: 现在,一个索引只能包含一个隐含的类型 _doc。当你索引文档时,不再需要在 URL 中指定类型,例如 POST /my_index/_doc/1

  • 重要提示: 如果你学习的是较新的 Elasticsearch 版本(7.x 或以上),请忘记 Type 的概念,专注于 Index 和 Document。

2.4 分片 (Shard)

  • 定义: 索引的物理组成部分。一个索引被分割成一个或多个分片。
  • 特点:

    • 独立:每个分片是一个独立的 Lucene 索引,可以在集群中的任何节点上托管。
    • 分布式:分片允许你水平扩展索引,处理远超单台服务器存储能力的数据。
    • 并行处理:搜索请求可以并行地在多个分片上执行,提高搜索速度。
    • 主分片 (Primary Shard):创建索引时指定的主分片数量 (number_of_shards) 决定了索引被分割的份数。一旦创建,主分片数量不能改变。
  • 重要性: 分片是 Elasticsearch 实现分布式和扩展性的基础。

2.5 副本 (Replica)

  • 定义: 主分片的拷贝。每个主分片可以有零个或多个副本。
  • 特点:

    • 高可用性:当主分片所在的节点发生故障时,副本可以晋升为主分片,保证数据不丢失和服务的可用性。
    • 读取扩展:搜索请求不仅可以在主分片上执行,也可以在副本上执行,增加了系统的吞吐量。
    • 动态调整:副本数量 (number_of_replicas) 可以在索引创建后动态调整。
  • 重要性: 副本是 Elasticsearch 实现高可用性和提高读取性能的基础。一个健康的分片组通常由一个主分片和零个或多个副本组成。

2.6 节点 (Node)

  • 定义: 运行着一个 Elasticsearch 实例的服务器。
  • 角色: 节点可以扮演不同的角色,例如:

    • 主节点 (Master Node):负责管理集群状态、创建/删除索引、分配分片等。
    • 数据节点 (Data Node):负责存储分片数据、执行数据相关的操作(如搜索、索引)。
    • 协调节点 (Coordinating Node):处理客户端请求,将请求路由到合适的节点,并汇总结果。
    • 学习节点 (Machine Learning Node),等等。
  • 集群: 多个节点组成的集合称为一个集群。

2.7 集群 (Cluster)

  • 定义: 由一个或多个共享相同 cluster.name 的节点组成的集合。
  • 特点:

    • 统一管理:节点之间相互发现并协同工作,共同提供服务。
    • 数据分布:数据(分片)分布在集群的各个节点上。
    • 高可用性:集群中至少有一个主节点负责管理,其他节点提供数据存储和处理能力。
  • 重要性: 集群是 Elasticsearch 分布式能力的体现,提供了整体的数据存储、搜索和分析能力。

第三章:快速入门实践——安装与基本操作

理论知识掌握得差不多了,现在让我们通过实践来亲身体验 Elasticsearch。最快捷的方式是使用 Docker 或 Elasticsearch 官方提供的压缩包进行安装。这里我们以 Docker 为例,因为它最简单快捷。

3.1 安装 Elasticsearch 和 Kibana (使用 Docker)

确保你已经安装了 Docker。然后执行以下命令来启动一个单节点 Elasticsearch 集群和一个 Kibana 实例:

“`bash

创建一个 Docker 网络,让 Elasticsearch 和 Kibana 可以互相通信

docker network create elastic-net

运行 Elasticsearch 容器

设置 discovery.type=single-node 启动单节点模式

设置 ES_JAVA_OPTS 避免内存问题(生产环境需根据实际情况调整)

docker run -d –name elasticsearch \
–net elastic-net \
-p 9200:9200 -p 9300:9300 \
-e “discovery.type=single-node” \
-e “ES_JAVA_OPTS=-Xms512m -Xmx512m” \
docker.elastic.co/elasticsearch/elasticsearch:8.10.0 # 使用一个具体的版本,例如 8.10.0
# 注意:8.x 版本默认开启安全特性,需要获取密码和证书指纹。简单起见,这里暂不启用安全(生产环境必须启用)
# 对于8.x,更简单的入门方式是 let Elasticsearch generate security configs, then inspect logs.
# 例如: docker run –rm docker.elastic.co/elasticsearch/elasticsearch:8.10.0 esusers passwd -u elastic
# 本文为了简化入门,建议使用 7.x 版本或者在 8.x 关闭安全(不推荐生产环境)
# 或者按照8.x官方文档获取并使用 auto-generated security settings.
# 此处为了简化,我们假定你已按照官方文档处理了 8.x 的安全设置或使用了 7.x 版本
# 如果使用 7.x 版本,可能不需要处理安全,命令会更简单。

运行 Kibana 容器

连接到之前创建的网络

配置 KIBANA_ELASTICSEARCH_HOSTS 指向 Elasticsearch 容器

docker run -d –name kibana \
–net elastic-net \
-p 5601:5601 \
-e “KIBANA_ELASTICSEARCH_HOSTS=http://elasticsearch:9200” \
docker.elastic.co/kibana/kibana:8.10.0 # 与 Elasticsearch 版本保持一致

检查容器是否启动成功

docker ps
“`
注意: Elasticsearch 8.x 版本默认开启了安全特性。上述 Docker 命令为了入门简化,并未包含复杂的安全配置(如密码、证书)。在实际生产环境中,强烈建议遵循官方文档启用并配置安全功能。对于初学者,如果你觉得 8.x 的安全配置复杂,可以考虑先从 7.x 版本开始学习,或者按照 8.x 官方文档的 single-node 模式指引,它会生成临时的用户名密码供你使用。

启动成功后,等待几分钟让服务完全就绪。你可以通过浏览器访问 http://localhost:9200 查看 Elasticsearch 的信息(如果是 8.x 带安全,需要认证),访问 http://localhost:5601 打开 Kibana 界面。

3.2 使用 Kibana Dev Tools 进行交互

Kibana 提供了一个非常有用的工具叫做 Dev Tools (开发工具),你可以在其中直接输入并执行 Elasticsearch 的 REST API 请求。打开 Kibana,找到 “Management” 或 “Dev Tools”,点击 “Console”。

Console 界面分为左右两栏,左边输入请求,右边显示响应。

3.3 基本 CRUD 操作 (创建、读取、更新、删除 文档)

我们将使用一个简单的例子:索引一些书籍的信息。

创建文档 (Create Document)

可以使用 POST 或 PUT 方法。POST 到 /_doc 让 Elasticsearch 自动生成 ID;PUT 到 /_doc/<id> 指定 ID。

  • 自动生成 ID:

    json
    POST /books/_doc
    {
    "title": "Elasticsearch: The Definitive Guide",
    "author": "Clinton Gormley",
    "publish_year": 2015,
    "price": 49.99,
    "tags": ["elasticsearch", "search", "guide"]
    }

    执行后,你会得到一个响应,其中包含文档的 _index, _id, _version 等信息。注意 _id 是 Elasticsearch 自动生成的。

  • 指定 ID:

    json
    PUT /books/_doc/book_1
    {
    "title": "Learning Elasticsearch",
    "author": "Bharvi Dixit",
    "publish_year": 2018,
    "price": 35.00,
    "tags": ["elasticsearch", "learning"]
    }

    执行后,ID 为 book_1 的文档将被创建或完全替换。

再创建几个文档用于后续搜索:

“`json
PUT /books/_doc/book_2
{
“title”: “Relevant Search”,
“author”: “Doug Turnbull”,
“publish_year”: 2016,
“price”: 45.00,
“tags”: [“search”, “relevance”]
}

PUT /books/_doc/book_3
{
“title”: “Practical Elasticsearch 8”,
“author”: “Waheed Shafran”,
“publish_year”: 2022,
“price”: 55.00,
“tags”: [“elasticsearch”, “practical”, “guide”]
}
“`

读取文档 (Read Document)

使用 GET 方法,指定索引和文档 ID。

json
GET /books/_doc/book_1

响应将包含文档的源数据 (_source) 以及元信息 (_index, _id, _version, _seq_no, _primary_term)。

更新文档 (Update Document)

可以使用 PUT 方法完全替换文档,或者使用 POST 到 /_update 进行局部更新。局部更新更常用,因为它只修改指定字段而保留其他字段。

  • 局部更新 (使用 _update):

    json
    POST /books/_update/book_1
    {
    "doc": {
    "price": 30.00,
    "tags": ["elasticsearch", "learning", "updated"]
    }
    }

    执行后,book_1 文档的 pricetags 字段将被更新,其他字段(如 title, author)保持不变。

  • 完全替换 (使用 PUT):

    json
    PUT /books/_doc/book_2
    {
    "title": "Relevant Search Updated",
    "author": "Doug Turnbull",
    "publish_year": 2016,
    "price": 50.00,
    "language": "English" # 添加新字段
    }

    这将用新的 JSON 对象完全替换 ID 为 book_2 的文档。

删除文档 (Delete Document)

使用 DELETE 方法,指定索引和文档 ID。

json
DELETE /books/_doc/book_1

执行后,ID 为 book_1 的文档将被标记为删除(逻辑删除,物理删除会在后台进行)。

3.4 基本搜索 (Basic Search)

Elasticsearch 的搜索功能非常强大,使用 Query DSL (Domain Specific Language) 来构建搜索请求,这是一个 JSON 格式的查询语句。搜索请求发送到 /_search 端点。

  • 搜索所有文档:

    json
    GET /books/_search

    这将返回 books 索引中的所有文档(默认返回前 10 条)。

  • 全文搜索 (使用 match 查询):

    搜索标题或标签中包含 “elasticsearch” 的书籍。match 查询会对查询字符串进行分词,然后匹配文档字段分词后的词项。

    json
    GET /books/_search
    {
    "query": {
    "match": {
    "title": "Elasticsearch"
    }
    }
    }

    搜索标签中包含 “guide” 的书籍:

    json
    GET /books/_search
    {
    "query": {
    "match": {
    "tags": "guide"
    }
    }
    }

  • 精确值匹配 (使用 termterms 查询):

    搜索作者为 “Doug Turnbull” 的书籍。对于精确匹配,通常需要匹配字段的原始值,这需要使用 .keyword 后缀(如果字段是文本类型且开启了 keyword 映射)。

    json
    GET /books/_search
    {
    "query": {
    "term": {
    "author.keyword": "Doug Turnbull"
    }
    }
    }

    注意: 如果你在索引文档时没有显式定义 author 字段的映射,Elasticsearch 可能会动态生成一个包含 textkeyword 子字段的映射。.keyword 字段存储字段的精确原始值,适合用于精确匹配、排序和聚合。

  • 范围搜索 (使用 range 查询):

    搜索价格在 40 到 50 之间的书籍。

    json
    GET /books/_search
    {
    "query": {
    "range": {
    "price": {
    "gte": 40, # 大于等于
    "lte": 50 # 小于等于
    }
    }
    }
    }

  • 组合查询 (使用 bool 查询):

    bool 查询用于组合多个查询条件,例如 must (必须匹配), filter (必须匹配,但不计算相关性得分), should (应该匹配,影响得分), must_not (必须不匹配)。

    搜索标题包含 “Elasticsearch” 且价格小于 50 的书籍:

    json
    GET /books/_search
    {
    "query": {
    "bool": {
    "must": [
    {
    "match": {
    "title": "Elasticsearch"
    }
    }
    ],
    "filter": [ # 使用 filter 以提高性能,因为价格范围不需要计算相关性
    {
    "range": {
    "price": {
    "lt": 50 # 小于
    }
    }
    }
    ]
    }
    }
    }

3.5 理解搜索结果

Elasticsearch 的搜索结果通常包含以下重要部分:

  • "hits": 包含搜索命中的文档列表。
    • "total": 匹配到的总文档数。
    • "hits" 数组: 具体的搜索结果,每个元素代表一个匹配的文档。
      • "_index": 文档所在的索引。
      • "_id": 文档的 ID。
      • "_score": 文档与查询的相关性得分,得分越高表示越相关。
      • "_source": 文档的原始 JSON 数据。

第四章:Kibana——你的可视化与管理利器

虽然我们可以通过 REST API 直接与 Elasticsearch 交互,但 Kibana 提供了一个用户友好的界面,极大地简化了数据探索、可视化和集群管理。

  • Discover: 用于探索 Elasticsearch 中的数据。你可以选择一个或多个索引模式,查看文档列表,根据时间范围过滤数据,并进行简单的搜索。
  • Visualize: 基于你的数据创建各种图表和可视化,如柱状图、折线图、饼图、地图等。
  • Dashboard: 将多个可视化组件组合到一个页面上,创建自定义的数据仪表板。
  • Dev Tools: 前面已经介绍过,用于执行 REST API 请求。
  • Management: 用于管理 Elasticsearch 索引、快照、用户权限等。

学会使用 Kibana 将让你的 Elasticsearch 之旅更加高效和愉快。

第五章:更进一步——探索高级特性 (简述)

本教程旨在入门,但 Elasticsearch 的能力远不止于此。以下是一些值得你深入探索的高级特性:

  • 映射 (Mapping): 精确控制字段的数据类型、如何被索引、使用何种分词器等。理解映射是构建高效搜索的关键。
  • 分词 (Analysis): Elasticsearch 在索引和搜索文本时会进行分词处理。了解分词器、Tokenizer 和 Token Filter 是优化全文搜索效果的基础。
  • 聚合 (Aggregations): 对搜索结果进行分组、统计、计算指标,实现复杂的数据分析和商业智能。这是 Elasticsearch 作为分析引擎的核心能力。
  • 索引生命周期管理 (ILM): 自动管理索引的生命周期,例如在数据变老时将索引移动到性能较低但成本更低的存储层,或者自动删除旧数据。
  • 快照与恢复 (Snapshot and Restore): 对集群数据进行备份和恢复。
  • 安全 (Security): 用户认证、授权、加密通信等。在生产环境中至关重要。
  • Watcher & Alerting: 监控 Elasticsearch 集群或数据变化,并在满足条件时触发告警。

结论

恭喜你!通过阅读本文,你已经对 Elasticsearch 有了一个全面的认识,掌握了它的核心概念,并通过实践了解了如何进行基本的数据操作和搜索。Elasticsearch 是一个功能强大且用途广泛的工具,它是构建现代搜索、日志分析、监控和数据分析平台的重要基石。

入门仅仅是开始,Elasticsearch 还有许多高级特性和优化技巧等待你去探索。最有效的学习方式是不断实践,尝试将你的数据放入 Elasticsearch,使用 Kibana 进行探索和可视化,并参考官方文档解决遇到的问题。

希望这篇教程能为你打开通往 Elasticsearch 世界的大门,祝你在数据探索和分析的旅程中取得成功!


发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部