零基础学习 Elasticsearch:完整教程
1. 什么是 Elasticsearch?
Elasticsearch(简称 ES)是一个基于 Apache Lucene™ 的开源、分布式、RESTful 搜索引擎和分析引擎。它能够快速地存储、搜索和分析大量数据,广泛应用于日志分析、全文搜索、指标分析、安全智能等领域。
核心特点:
- 分布式: 可以在多台服务器上运行,实现数据的高可用和可伸缩性。
- 实时性: 几乎实时地索引和搜索数据。
- RESTful API: 通过 HTTP 协议进行交互,操作简便。
- 全文搜索: 强大的文本搜索能力,支持多种语言和复杂的查询。
- 分析能力: 提供丰富的聚合功能,可以对数据进行深度分析。
- 高可用性: 自动处理节点故障,数据不易丢失。
- 可伸缩性: 随着数据量的增长,可以方便地扩展集群。
2. 为什么学习 Elasticsearch?
- 行业需求: 大数据时代,数据搜索和分析成为核心能力,ES 是其中的佼佼者。
- 强大的功能: 无论是日志系统(ELK Stack 中的 E)、电商搜索、还是业务数据分析,ES 都能提供强力支持。
- 生态系统: 围绕 ES 有 Kibana(数据可视化)、Logstash(数据收集)等丰富的工具,构成完整的解决方案。
- 技术趋势: 掌握 ES 能显著提升您的技术竞争力。
3. 核心概念
在深入学习之前,了解 ES 的一些核心概念至关重要:
- 文档 (Document): ES 中的最小数据单元,以 JSON 格式存储。可以类比为关系型数据库中的一行记录。
- 例如:
{"user": "Alice", "age": 30, "city": "New York"}
- 例如:
- 索引 (Index): 文档的集合。可以类比为关系型数据库中的一个数据库。一个集群可以有多个索引。
- 例如:
users索引存储所有用户文档,logs索引存储所有日志文档。
- 例如:
- 类型 (Type): 在 Elasticsearch 7.x 版本及以后已被移除或不推荐使用。在旧版本中,它是索引中文档的逻辑分类。
- 字段 (Field): 文档中的键值对,例如
user、age、city。 - 映射 (Mapping): 定义了文档及其字段的类型(如
string,integer,date)、如何存储、如何被索引以及如何被搜索。可以类比为关系型数据库中的表结构定义。 - 分片 (Shard): 将一个索引分成多个物理分片,每个分片都是一个独立的 Lucene 索引。这使得 ES 能够水平扩展和分布式处理。
- 主分片 (Primary Shard): 负责接收索引请求,每个文档只存储在一个主分片中。
- 副本分片 (Replica Shard): 主分片的精确副本,用于提高查询性能和保证高可用性。当主分片故障时,副本分片可以提升为主分片。
- 节点 (Node): 运行一个 Elasticsearch 实例的服务器。
- 集群 (Cluster): 一个或多个节点组成的集合,它们共同存储数据并提供索引和搜索能力。
4. 环境搭建
我们将使用 Docker 快速搭建一个单节点 Elasticsearch 环境。
前提条件: 安装 Docker Desktop。
-
拉取 Elasticsearch 镜像:
bash
docker pull docker.elastic.co/elasticsearch/elasticsearch:7.17.0
(推荐使用稳定版本,这里以 7.17.0 为例) -
运行 Elasticsearch 容器:
bash
docker run -d --name elasticsearch \
-p 9200:9200 -p 9300:9300 \
-e "discovery.type=single-node" \
-e "xpack.security.enabled=false" \
-e "ES_JAVA_OPTS=-Xms512m -Xmx512m" \
docker.elastic.co/elasticsearch/elasticsearch:7.17.0-d: 后台运行。--name elasticsearch: 为容器命名。-p 9200:9200: 将容器的 9200 端口映射到主机的 9200 端口(HTTP API)。-p 9300:9300: 将容器的 9300 端口映射到主机的 9300 端口(节点间通信)。discovery.type=single-node: 声明这是一个单节点集群(生产环境不建议)。xpack.security.enabled=false: 禁用安全认证,方便初学(生产环境务必开启)。ES_JAVA_OPTS=-Xms512m -Xmx512m: 设置 JVM 内存,根据您的机器配置调整。
-
验证 Elasticsearch 是否启动:
打开浏览器访问http://localhost:9200,如果看到包含tagline: "You Know, for Search"的 JSON 响应,说明 ES 成功启动。
5. 基本操作:CRUD
Elasticsearch 通过 RESTful API 进行操作,我们可以使用 curl 命令(或 Postman/Insomnia 等工具)来演示。
5.1 创建/索引文档 (Create/Index Document)
使用 HTTP POST 或 PUT 请求向索引添加文档。PUT 请求需要指定文档 ID,POST 请求则由 ES 自动生成 ID。
自动生成 ID (POST):
bash
curl -X POST "localhost:9200/my_index/_doc?pretty" -H 'Content-Type: application/json' -d'
{
"title": "零基础学习 Elasticsearch",
"author": "Gemini AI",
"publish_date": "2025-12-31",
"tags": ["Elasticsearch", "教程", "大数据", "搜索"],
"content": "这是一篇关于零基础学习 Elasticsearch 的完整教程,帮助您快速入门。"
}
'
指定 ID (PUT):
bash
curl -X PUT "localhost:9200/my_index/_doc/1?pretty" -H 'Content-Type: application/json' -d'
{
"title": "Elastic Stack 入门",
"author": "Elastic Official",
"publish_date": "2024-01-15",
"tags": ["Elastic", "Kibana", "Logstash"],
"content": "学习 Elastic Stack 的基本组件和使用方法。"
}
'
5.2 获取文档 (Read Document)
使用 HTTP GET 请求根据文档 ID 获取文档。
bash
curl -X GET "localhost:9200/my_index/_doc/1?pretty"
5.3 更新文档 (Update Document)
使用 HTTP POST 请求到 _update 端点更新文档。可以部分更新。
bash
curl -X POST "localhost:9200/my_index/_update/1?pretty" -H 'Content-Type: application/json' -d'
{
"doc": {
"tags": ["Elastic", "Kibana", "Logstash", "更新"],
"version": 2
}
}
'
你也可以通过 PUT 指定文档 ID 覆盖整个文档,但 _update 更常用且高效。
5.4 删除文档 (Delete Document)
使用 HTTP DELETE 请求根据文档 ID 删除文档。
bash
curl -X DELETE "localhost:9200/my_index/_doc/1?pretty"
5.5 删除索引 (Delete Index)
删除整个索引及其所有文档。
bash
curl -X DELETE "localhost:9200/my_index?pretty"
6. 搜索 (Search)
搜索是 Elasticsearch 的核心功能。
6.1 基本搜索 (Match All)
搜索索引中的所有文档。
bash
curl -X GET "localhost:9200/my_index/_search?pretty"
6.2 查询字符串搜索 (Query String Search)
通过 URL 参数进行简单的查询。
bash
curl -X GET "localhost:9200/my_index/_search?q=教程&pretty"
这将搜索所有字段中包含“教程”的文档。
6.3 请求体搜索 (Request Body Search – Query DSL)
最常用和强大的搜索方式,使用 Elasticsearch 的查询领域特定语言 (Query DSL)。
匹配查询 (Match Query): 搜索特定字段的值。
bash
curl -X GET "localhost:9200/my_index/_search?pretty" -H 'Content-Type: application/json' -d'
{
"query": {
"match": {
"title": "教程"
}
}
}
'
布尔查询 (Bool Query): 组合多个查询条件(must、should、must_not、filter)。
must: 必须匹配。should: 应该匹配(得分越高越好,至少一个 should 匹配)。must_not: 必须不匹配。filter: 必须匹配,但不参与评分(用于精确过滤)。
bash
curl -X GET "localhost:9200/my_index/_search?pretty" -H 'Content-Type: application/json' -d'
{
"query": {
"bool": {
"must": [
{ "match": { "tags": "Elasticsearch" } }
],
"filter": [
{ "range": { "publish_date": { "gte": "2025-01-01" } } }
],
"should": [
{ "match": { "author": "Gemini AI" } }
],
"must_not": [
{ "match": { "title": "旧版本" } }
]
}
}
}
'
范围查询 (Range Query): 查找某个字段在指定范围内的文档。
bash
curl -X GET "localhost:9200/my_index/_search?pretty" -H 'Content-Type: application/json' -d'
{
"query": {
"range": {
"publish_date": {
"gte": "2024-01-01",
"lte": "2025-12-31",
"format": "yyyy-MM-dd"
}
}
}
}
'
7. 聚合 (Aggregations)
聚合是 Elasticsearch 强大的分析功能,可以对数据进行统计、分组和计算。
示例数据:
我们先多添加几条文档,以便演示聚合。
bash
curl -X POST "localhost:9200/products/_doc?pretty" -H 'Content-Type: application/json' -d'
{"name": "Laptop", "category": "Electronics", "price": 1200, "stock": 50}
'
curl -X POST "localhost:9200/products/_doc?pretty" -H 'Content-Type: application/json' -d'
{"name": "Mouse", "category": "Electronics", "price": 25, "stock": 200}
'
curl -X POST "localhost:9200/products/_doc?pretty" -H 'Content-Type: application/json' -d'
{"name": "Keyboard", "category": "Electronics", "price": 75, "stock": 150}
'
curl -X POST "localhost:9200/products/_doc?pretty" -H 'Content-Type: application/json' -d'
{"name": "T-Shirt", "category": "Apparel", "price": 20, "stock": 300}
'
curl -X POST "localhost:9200/products/_doc?pretty" -H 'Content-Type: application/json' -d'
{"name": "Jeans", "category": "Apparel", "price": 50, "stock": 100}
'
Terms 聚合 (Terms Aggregation): 按字段分组并计数,类似于 SQL 中的 GROUP BY。
bash
curl -X GET "localhost:9200/products/_search?size=0&pretty" -H 'Content-Type: application/json' -d'
{
"aggs": {
"products_by_category": {
"terms": {
"field": "category.keyword"
}
}
}
}
'
* size=0: 我们只关心聚合结果,不返回实际文档。
* category.keyword: 对 category 字段进行聚合,通常使用 .keyword 后缀来确保对字段的精确值进行分组,而不是其分词后的结果。
Metrics 聚合 (Metrics Aggregation): 计算字段的统计信息(min, max, avg, sum 等)。
bash
curl -X GET "localhost:9200/products/_search?size=0&pretty" -H 'Content-Type: application/json' -d'
{
"aggs": {
"avg_price": {
"avg": {
"field": "price"
}
},
"total_stock": {
"sum": {
"field": "stock"
}
}
}
}
'
嵌套聚合 (Nested Aggregation): 将多个聚合组合使用。例如,按类别分组,然后计算每个类别的平均价格。
bash
curl -X GET "localhost:9200/products/_search?size=0&pretty" -H 'Content-Type: application/json' -d'
{
"aggs": {
"products_by_category": {
"terms": {
"field": "category.keyword"
},
"aggs": {
"avg_price_per_category": {
"avg": {
"field": "price"
}
}
}
}
}
}
'
8. 映射 (Mapping)
映射定义了字段的数据类型和索引方式。虽然 ES 通常会进行动态映射,但在生产环境中显式定义映射是最佳实践。
查看现有映射:
bash
curl -X GET "localhost:9200/products/_mapping?pretty"
创建/更新映射(在创建索引时指定):
bash
curl -X PUT "localhost:9200/my_new_index?pretty" -H 'Content-Type: application/json' -d'
{
"mappings": {
"properties": {
"id": { "type": "keyword" },
"product_name": { "type": "text" },
"description": { "type": "text" },
"category": { "type": "keyword" },
"price": { "type": "float" },
"on_sale": { "type": "boolean" },
"created_at": { "type": "date", "format": "yyyy-MM-dd HH:mm:ss" }
}
}
}
'
* text: 适用于全文搜索的文本字段,会进行分词处理。
* keyword: 适用于精确匹配(如标签、ID、类别),不会分词。
* float, integer, long, double: 数字类型。
* boolean: 布尔类型。
* date: 日期类型。
9. 结合 Kibana
Kibana 是一个与 Elasticsearch 配合使用的开源数据可视化和管理工具。
-
拉取 Kibana 镜像:
bash
docker pull docker.elastic.co/kibana/kibana:7.17.0 -
运行 Kibana 容器:
bash
docker run -d --name kibana \
-p 5601:5601 \
--link elasticsearch \
-e "ELASTICSEARCH_HOSTS=http://elasticsearch:9200" \
docker.elastic.co/kibana/kibana:7.17.0--link elasticsearch: 允许 Kibana 通过elasticsearch别名访问 ES 容器。ELASTICSEARCH_HOSTS: 指定 Elasticsearch 的地址。
-
访问 Kibana:
打开浏览器访问http://localhost:5601。
进入 Kibana 后,您可以在 “Dev Tools” 中直接执行 Elasticsearch 的 REST API 请求,也可以创建索引模式、发现数据、构建可视化图表和仪表板。
10. 进阶学习方向
- ELK Stack: 深入学习 Logstash(数据收集)、Kibana(数据可视化)与 Elasticsearch 的整合。
- 集群管理: 了解多节点部署、数据均衡、故障恢复、快照与恢复等。
- 性能优化: 映射优化、查询优化、JVM 调优、硬件选择。
- 安全: X-Pack 安全功能(认证、授权、加密)。
- 高级查询: 脚本查询、父子文档、geo 空间搜索等。
- 插件开发: 根据需求开发自定义插件。
总结
本教程从零开始,带您了解了 Elasticsearch 的基本概念、环境搭建、CRUD 操作、查询和聚合功能,并介绍了 Kibana 的集成。这只是冰山一角,Elasticsearch 的功能远不止于此。持续学习和实践是掌握这门强大技术的关键。祝您学习愉快!