Elasticsearch 入门教程 – wiki基地


Elasticsearch 入门教程:从概念到实战

前言

在当今数据爆炸的时代,如何快速、准确地搜索和分析海量数据成为了企业面临的巨大挑战。传统的关系型数据库在处理全文搜索、复杂分析和实时数据流方面往往显得力不从心。正是在这样的背景下,Elasticsearch 应运而生,并迅速成为业界领先的分布式搜索和分析引擎。

Elasticsearch 不仅提供了强大的全文搜索能力,还能进行实时的结构化数据分析、日志和事件数据处理、监控以及报表生成。它的分布式特性使其具有出色的可扩展性和容错性,能够轻松应对 PB 级别的数据。

本教程将带领你从零开始,逐步了解 Elasticsearch 的核心概念、安装部署、基本操作以及一些进阶知识,助你叩开 Elasticsearch 的大门。

第一部分:理解 Elasticsearch – 它是什么以及为什么使用它?

1. Elasticsearch 是什么?

Elasticsearch 是一个基于 Apache Lucene 构建的开源、分布式的 RESTful 搜索和分析引擎。简单来说,你可以把它看作一个高度可伸缩、能快速存储、搜索和分析大量数据的数据库。

核心特性:

  • 分布式 (Distributed): 数据被分散存储在多个节点上,可以水平扩展。
  • 实时性 (Near Realtime): 从数据索引到可被搜索只有很短的延迟(通常是秒级)。
  • RESTful API: 使用标准的 HTTP 请求进行交互,易于使用和集成。
  • 全文搜索 (Full-text Search): 强大的文本搜索能力,支持复杂的查询和排名。
  • 结构化搜索 (Structured Search): 支持按字段进行精确匹配、范围查询等。
  • 分析 (Analytics): 强大的聚合功能 (Aggregations) ,可以进行复杂的数据统计和分析。
  • 高可用性 (High Availability): 通过副本机制保证数据不丢失,即使部分节点失效。

2. 为什么选择 Elasticsearch?

  • 速度快: 基于倒排索引 (Inverted Index),使其在海量数据中进行搜索和过滤异常迅速。
  • 易于扩展: 分布式架构使得水平扩展非常简单,只需增加节点即可。
  • 功能强大: 除了搜索,还提供丰富的分析、聚合功能,适用于多种场景。
  • 生态系统完善: 是 Elastic Stack (ELK/ECK) 的核心,与 Logstash (数据收集)、Beats (轻量级数据采集器) 和 Kibana (可视化界面) 紧密集成。
  • RESTful API: 对开发者友好,易于与其他应用集成。
  • 社区活跃: 开源项目,拥有庞大的用户社区和丰富的文档资源。

3. 常见的应用场景

  • 日志和事件数据分析: 使用 Elastic Stack (ELK) 收集、存储、搜索和分析服务器日志、应用日志等。
  • 全文搜索: 为网站、电商平台、文档管理系统等提供强大的站内搜索功能。
  • 性能监控: 收集和分析应用程序和系统的性能指标。
  • 地理位置搜索: 支持地理位置数据的索引和搜索。
  • 安全分析: 分析安全日志和事件,检测异常行为。
  • 业务分析: 对业务数据进行实时分析和报表生成。

第二部分:Elasticsearch 核心概念解析

理解这些核心概念是掌握 Elasticsearch 的基础。

1. Cluster (集群)

一个集群由一个或多个节点 (Node) 组成,它们协同工作,共同存储和处理数据。集群具有唯一的名称 (默认为 elasticsearch),节点通过集群名称相互发现和加入。集群提供了数据的分布式存储、搜索和分析能力。

2. Node (节点)

一个节点是一个 Elasticsearch 实例,它是集群中的一个独立运行的服务。节点启动时会尝试加入一个指定的集群。节点可以根据职责不同扮演不同的角色(如主节点、数据节点、协调节点等),但在入门阶段,可以先将其视为一个具有多种能力的实例。

3. Index (索引)

索引是 Elasticsearch 中存储数据的地方,类似于关系型数据库中的“数据库”或“表”。一个索引是相关文档的集合。例如,你可以有一个用于存储客户数据的索引,一个用于存储产品数据的索引,或者一个用于存储日志的索引。索引名称必须小写。

4. Document (文档)

文档是 Elasticsearch 中可被索引的最小单位,类似于关系型数据库中的“行”或“记录”。文档是以 JSON (JavaScript Object Notation) 格式表示的一组字段 (Field) 的集合。每个文档在索引中都有一个唯一的 ID。

5. Field (字段)

字段是文档中的一个键值对,类似于关系型数据库中的“列”。字段的名称和值组成了文档的内容。例如,一个客户文档可能有 nameagecity 等字段。

6. Type (类型) – 注意:在新版本中已弃用

在 Elasticsearch 6.x 及之前的版本中,一个索引可以包含多个类型 (Type),类似于关系型数据库中同一个数据库下的不同表。然而,在 Elasticsearch 7.x 及之后的版本中,一个索引只能包含一个默认的类型 _doc。这是为了简化概念并避免一些潜在的性能问题。在学习新版本时,可以直接忽略类型的概念,将索引视为直接包含文档的容器。

7. Mapping (映射)

映射定义了文档及其字段的结构和数据类型,类似于关系型数据库中的“表结构”或“Schema”。映射告诉 Elasticsearch 如何索引每个字段的数据(例如,字符串字段是作为全文索引还是精确值索引),以及字段的数据类型(如 text`keywordintegerdate 等)。如果创建文档时没有明确指定映射,Elasticsearch 会尝试动态猜测字段的类型并自动创建映射 (Dynamic Mapping)。

8. Shard (分片)

索引可能存储大量数据,单个节点可能无法容纳或提供足够的性能。为了解决这个问题,Elasticsearch 将索引划分为多个物理上的“分片”。每个分片本身就是一个独立的 Lucene 索引。分片可以在集群中的不同节点上。这使得数据可以分布式存储,查询可以并行执行,从而提高了性能和可扩展性。分片的数量在索引创建时确定,之后不能修改。

9. Replica (副本)

为了提高可用性和容错性,Elasticsearch 允许为每个分片创建多个副本。副本是分片的一个完整拷贝。副本分片与原始主分片 (Primary Shard) 存储在不同的节点上。如果某个节点故障,包含主分片或副本分片的另一个节点仍然可以提供服务。副本分片也可以处理读请求,提高了搜索吞吐量。副本的数量可以在索引创建后动态修改。

总结分片与副本: 一个索引由 N 个主分片组成,每个主分片可以有 R 个副本。总分片数量 = N * (1 + R)

第三部分:安装与启动 Elasticsearch

安装 Elasticsearch 有多种方式,这里介绍最常见的几种。

1. 前置条件

  • Java 环境: Elasticsearch 需要 Java 运行环境。请确保你的系统上安装了 Java Development Kit (JDK),推荐使用 Oracle JDK 或 OpenJDK 11 或更高版本(具体版本要求请查阅对应 Elasticsearch 版本的官方文档)。

2. 下载与安装

访问 Elasticsearch 官方下载页面 (https://www.elastic.co/cn/downloads/elasticsearch) 下载适合你操作系统的版本(如 .tar.gz.zip 文件)。

以 Linux 为例 (使用 .tar.gz 包):

  1. 下载安装包:
    bash
    wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-8.x.x-linux-x86_64.tar.gz

    (请将 8.x.x 替换为你下载的具体版本号)

  2. 解压:
    bash
    tar -xzf elasticsearch-8.x.x-linux-x86_64.tar.gz

  3. 进入解压目录:
    bash
    cd elasticsearch-8.x.x/

3. 配置 (可选但推荐)

编辑 config/elasticsearch.yml 文件进行基本配置。对于入门,可以先做一些简单设置:

  • 集群名称:
    yaml
    cluster.name: my-elasticsearch-cluster
  • 节点名称:
    yaml
    node.name: node-1
  • 绑定 IP (允许外部访问): 默认为 localhost,如果想让其他机器访问,需要改为 0.0.0.0 或具体 IP。注意:生产环境请务必配置安全设置!
    yaml
    network.host: 0.0.0.0
    http.port: 9200
  • 数据存储路径 (重要): 指定数据和日志的存储位置。
    yaml
    path.data: /path/to/your/data
    path.logs: /path/to/your/logs

    确保这些路径存在且 Elasticsearch 用户具有写入权限。

4. 启动 Elasticsearch

在 Elasticsearch 目录下运行启动脚本:

bash
./bin/elasticsearch

或者在后台运行 (推荐在生产环境):

bash
./bin/elasticsearch -d

首次启动注意事项 (针对新版本):

新版本的 Elasticsearch 默认开启了安全功能 (如 HTTPS 和用户认证)。首次启动时,它可能会生成一个默认的用户名 (elastic) 和密码,以及用于 Kibana 注册的 token。请务必记录这些信息!

5. 验证安装

启动成功后,可以通过浏览器或 curl 访问 Elasticsearch 的默认端口 9200:

bash
curl http://localhost:9200

如果开启了安全认证,你需要提供用户名和密码:

bash
curl --user "elastic:your_password" https://localhost:9200 --cacert config/certs/http_ca.crt

(这里的 your_password 是启动时生成的或你自己设置的密码,--cacert 参数指向 CA 证书路径)

成功的话,你会看到一个包含集群、节点、版本等信息的 JSON 响应。这表明 Elasticsearch 已经成功启动并运行。

第四部分:使用 RESTful API 进行基本操作

Elasticsearch 主要通过 RESTful API 进行交互。你可以使用 curl 命令行工具、Postman、Kibana Dev Tools 或各种语言的客户端库来发送 HTTP 请求。

准备工作:Kibana Dev Tools

对于初学者,强烈推荐安装并使用 Kibana。Kibana 是 Elastic Stack 的官方可视化工具,它提供了一个非常方便的 Dev Tools (开发工具) 控制台,可以直接输入和发送 Elasticsearch API 请求,并查看响应。

安装 Kibana 并连接到你的 Elasticsearch 集群后,打开 Dev Tools (通常在左侧导航栏)。你可以在左侧面板输入请求,在右侧面板查看结果。本教程将使用 Dev Tools 的语法风格来展示 API 调用。

Dev Tools 请求格式:

HTTP_METHOD /index_name/endpoint
{
"request_body": "..."
}

例如:

GET /_cat/indices?v

这将获取集群中的所有索引列表。

1. 管理索引

1.1 创建索引

使用 PUT 请求指定索引名称。

json
PUT /my_first_index

响应示例:

json
{
"acknowledged": true,
"shards_acknowledged": true,
"index": "my_first_index"
}

1.2 查看索引列表

使用 _cat/indices API 可以查看集群中的所有索引及其基本信息。?v 参数会显示表头。

json
GET /_cat/indices?v

1.3 查看特定索引信息

使用 GET 请求指定索引名称。

json
GET /my_first_index

1.4 删除索引

使用 DELETE 请求指定索引名称。

json
DELETE /my_first_index

响应示例:

json
{
"acknowledged": true
}

2. 管理文档 (CRUD)

文档是 Elasticsearch 中可被索引和搜索的数据单位。

2.1 添加文档 (Index Document)

可以使用 POSTPUT 请求添加文档。

  • 自动生成 ID: 使用 POST /index_name/_doc,Elasticsearch 会自动为文档生成一个唯一的 ID。

    json
    POST /my_first_index/_doc
    {
    "title": "Elasticsearch 入门教程",
    "author": "张三",
    "publish_date": "2023-10-27",
    "content": "这是一篇关于 Elasticsearch 的入门级详细教程,适合初学者阅读。"
    }

  • 指定 ID: 使用 PUT /index_name/_doc/{id},你可以指定文档的 ID。如果该 ID 已存在,则会更新文档;如果不存在,则会创建文档。

    json
    PUT /my_first_index/_doc/1
    {
    "title": "Elasticsearch 核心概念解析",
    "author": "李四",
    "publish_date": "2023-11-01",
    "content": "本文详细介绍了 Elasticsearch 的核心概念,如索引、文档、分片等。"
    }

响应示例(包含文档的索引、ID、版本等信息):

json
{
"_index": "my_first_index",
"_id": "...", // 自动生成的ID 或 指定的ID
"_version": 1,
"result": "created", // 或 "updated"
"_shards": {
"total": 2, // 主分片+副本分片
"successful": 1,
"failed": 0
},
"_seq_no": 0,
"_primary_term": 1
}

2.2 获取文档 (Get Document)

使用 GET 请求指定索引名称和文档 ID。

json
GET /my_first_index/_doc/1

响应示例:

json
{
"_index": "my_first_index",
"_id": "1",
"_version": 1,
"_seq_no": 0,
"_primary_term": 1,
"found": true,
"_source": { // _source 字段包含原始文档内容
"title": "Elasticsearch 核心概念解析",
"author": "李四",
"publish_date": "2023-11-01",
"content": "本文详细介绍了 Elasticsearch 的核心概念,如索引、文档、分片等。"
}
}

如果文档不存在,"found" 字段将为 false

2.3 更新文档 (Update Document)

可以使用 PUT 完整替换文档,或者使用 POST /_update 进行局部更新。推荐使用 _update,因为它更高效,只需发送需要修改的字段。

  • 完全替换 (Replace): 使用 PUT 指定文档 ID,提供新的完整文档内容。

    json
    PUT /my_first_index/_doc/1
    {
    "title": "Elasticsearch 核心概念 (修订版)", // 修改了标题
    "author": "李四",
    "publish_date": "2023-11-05", // 修改了发布日期
    "content": "本文详细介绍了 Elasticsearch 的核心概念,如索引、文档、分片等。内容已更新。" // 修改了内容
    }

    这会替换整个文档,版本号会增加。

  • 局部更新 (Partial Update): 使用 POST /_update/{id}doc 字段。

    json
    POST /my_first_index/_update/1
    {
    "doc": {
    "publish_date": "2023-11-06",
    "version": "v1.1" // 添加一个新字段
    }
    }

    这只会修改 publish_date 字段并添加 version 字段,文档的其他部分保持不变。版本号会增加。

2.4 删除文档 (Delete Document)

使用 DELETE 请求指定索引名称和文档 ID。

json
DELETE /my_first_index/_doc/1

响应示例:

json
{
"_index": "my_first_index",
"_id": "1",
"_version": 2, // 版本号增加
"result": "deleted",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 1,
"_primary_term": 1
}

3. 搜索文档 (Search Documents)

搜索是 Elasticsearch 最核心的功能。使用 _search 端点进行搜索。可以通过请求体发送复杂的查询。请求体中的查询语句使用 Query DSL (Domain Specific Language)。

3.1 基本搜索 (Match All)

不指定查询条件,返回索引中的所有文档 (默认为前10条)。

json
GET /my_first_index/_search

或者

json
GET /my_first_index/_search
{
"query": {
"match_all": {}
}
}

响应示例 (简化):

json
{
"took": 3, // 搜索花费的时间 (毫秒)
"timed_out": false,
"_shards": { // 搜索涉及的分片信息
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": { // 搜索结果
"total": { // 匹配到的总文档数
"value": 2,
"relation": "eq" // "eq" 表示精确计数
},
"max_score": 1.0, // 最高相关度得分
"hits": [ // 匹配到的文档列表 (默认为前10条)
{
"_index": "my_first_index",
"_id": "...",
"_score": 1.0,
"_source": { ... } // 原始文档内容
},
{
"_index": "my_first_index",
"_id": "...",
"_score": 1.0,
"_source": { ... }
}
// ... 其他文档
]
}
}

3.2 全文搜索 (Match Query)

使用 match 查询在特定文本字段中搜索关键词。Elasticsearch 会对文本字段进行分词后进行匹配。

json
GET /my_first_index/_search
{
"query": {
"match": {
"content": "教程"
}
}
}

这将搜索 content 字段中包含词语“教程”的文档。

3.3 精确匹配 (Term Query)

使用 term 查询进行精确匹配。通常用于非文本字段 (如数字、日期、keyword 类型的字符串) 或不想进行分词的精确值。

json
GET /my_first_index/_search
{
"query": {
"term": {
"author.keyword": "张三" // 注意使用 .keyword 后缀进行精确匹配
}
}
}

这将搜索 author.keyword 字段精确等于“张三”的文档。通常,字符串字段在映射时会同时创建 text 类型(用于全文搜索,会分词)和 keyword 类型(用于精确匹配,不分词),.keyword 后缀就是访问 keyword 子字段。

3.4 组合查询 (Bool Query)

使用 bool 查询组合多个查询条件,实现 AND, OR, NOT 的逻辑。

  • must: 必须匹配 (AND)
  • filter: 必须匹配,但计算相关度得分 (score) 时忽略此条件 (用于过滤,更快) (AND)
  • should: 应该匹配 (OR)
  • must_not: 必须不匹配 (NOT)

json
GET /my_first_index/_search
{
"query": {
"bool": {
"must": [
{ "match": { "title": "Elasticsearch" } },
{ "match": { "content": "教程" } }
],
"filter": [
{ "range": { "publish_date": { "gte": "2023-11-01" } } }
]
// "should": [ ... ],
// "must_not": [ ... ]
}
}
}

这将搜索标题包含“Elasticsearch”内容包含“教程”发布日期在 2023-11-01 及之后的文档。

3.5 排序 (Sort)

默认按相关度得分 (_score) 降序排序。可以使用 sort 字段指定其他排序规则。

json
GET /my_first_index/_search
{
"query": {
"match_all": {}
},
"sort": [
{ "publish_date": { "order": "desc" } }, // 按发布日期降序
{ "_score": { "order": "desc" } } // 再按相关度得分降序
]
}

3.6 分页 (Pagination)

使用 fromsize 参数进行分页。from 表示跳过的文档数,size 表示返回的文档数。

json
GET /my_first_index/_search
{
"query": {
"match_all": {}
},
"from": 10, // 从第11条结果开始
"size": 20 // 返回20条结果
}

注意:深度分页在大数据量下效率较低,生产环境推荐使用 search_after 或 Scroll API。

第五部分:进一步学习方向

本教程只是 Elasticsearch 的入门。要真正掌握它,还需要学习更多概念和功能:

1. Mapping (映射)

深入理解字段类型(text, keyword, integer, float, boolean, date, geo_point 等),以及如何手动创建和管理映射,这对于数据建模和搜索效果至关重要。理解分析器 (Analyzer) 如何影响文本字段的索引和搜索。

2. Aggregations (聚合)

聚合是 Elasticsearch 强大的分析功能,类似于 SQL 中的 GROUP BY, COUNT, SUM, AVG 等操作。可以用来进行数据统计、分组、指标计算,用于生成报表和仪表盘。

3. 分布式特性

了解集群健康状态 (_cluster/health)、节点角色、分片分配、故障转移等分布式相关的知识,这对于管理和维护一个高可用、高性能的 Elasticsearch 集群至关重要。

4. 其他重要概念和功能

  • 倒排索引 (Inverted Index): Elasticsearch 快速搜索的底层原理。
  • 相关度评分 (Relevance Scoring): 了解文档如何根据查询条件获得评分并排序。
  • 高亮显示 (Highlighting): 在搜索结果中标记匹配的关键词。
  • 建议搜索 (Suggesters): 提供搜索建议或纠错功能。
  • 同义词 (Synonyms): 配置同义词以提高搜索召回率。
  • Watcher/Alerting: 监控集群或数据变化并触发警报。
  • 安全性: 用户认证、授权、SSL/TLS 加密等。
  • 性能优化: 索引设计、查询优化、集群调优等。

5. Elastic Stack 其他组件

  • Kibana: 强大的可视化工具,除了 Dev Tools,还提供数据探索、图表、仪表盘等功能。
  • Logstash: 数据采集、转换和转发工具。
  • Beats: 轻量级数据采集器(Filebeat, Metricbeat 等)。

学习如何将这些组件结合使用,构建完整的数据处理和分析流水线。

总结

Elasticsearch 是一个功能强大、灵活且可扩展的分布式搜索和分析引擎。本教程带你了解了其核心概念、安装方法以及通过 RESTful API 进行的基本 CRUD 和搜索操作。

入门只是第一步。要真正发挥 Elasticsearch 的潜力,还需要深入学习其映射、聚合、分布式原理等更高级的概念和功能。结合 Elastic Stack 的其他组件,你可以构建强大的数据解决方案,应对各种复杂的数据挑战。

现在,动手实践吧!安装 Elasticsearch 和 Kibana,尝试本教程中的示例,并开始探索更丰富的功能。祝你在 Elasticsearch 的学习旅程中顺利前行!


发表评论

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

滚动至顶部