Elasticsearch 入门与实战教程 – wiki基地


Elasticsearch 入门与实战教程:从零开始构建强大的搜索与分析引擎

前言

在当今数据爆炸的时代,如何高效地存储、检索和分析海量数据成为了一个核心挑战。传统的关系型数据库在处理全文检索、实时分析和复杂的结构化/非结构化数据混合查询时往往显得力不从心。正是在这样的背景下,Elasticsearch 应运而生,并迅速成为全球领先的开源分布式搜索和分析引擎。

无论你是想为你的网站构建一个闪电般的搜索功能,还是需要对海量的日志数据进行实时监控和分析,亦或是构建一个强大的业务数据分析平台,Elasticsearch 都能提供强大的支持。

本文将带你从零开始,一步步走进 Elasticsearch 的世界。我们将详细讲解其核心概念、安装部署、基本数据操作、强大的搜索能力,并通过实战案例加深理解。

第一部分:初识 Elasticsearch

1.1 什么是 Elasticsearch?

Elasticsearch (简称 ES) 是一个基于 Apache Lucene™ 的开源分布式搜索和分析引擎。它以其分布式架构、高可用性、易扩展性和强大的实时搜索与分析能力而闻名。

主要特性:

  • 分布式: 数据分散存储在多个节点上,天然支持水平扩展,可以处理 PB 级别的数据。
  • 实时性: 数据写入后很快就可以被搜索到(近实时)。
  • 全文检索: 基于 Lucene,提供强大的全文搜索功能,支持各种复杂的查询、过滤、排序和高亮。
  • 分析功能: 内置强大的聚合(Aggregations)框架,可以对数据进行分组、计算统计指标,实现实时的数据分析和可视化。
  • RESTful API: 提供简单易用的 RESTful 接口进行数据交互和集群管理。
  • 高可用性: 通过复制(Replicas)机制保证数据冗余,节点故障时可以自动故障转移。
  • 易扩展: 通过增加节点即可实现集群容量和吞吐量的扩展。

1.2 Elasticsearch 的应用场景

Elasticsearch 被广泛应用于各种领域:

  • 站内搜索/电商搜索: 为网站、App、电商平台提供快速、精准、智能的搜索体验。
  • 日志分析: 与 Logstash、Kibana 组成 ELK 技术栈(Elastic Stack),用于收集、处理、存储、搜索和可视化日志数据。
  • 指标监控与分析: 存储和分析应用、服务器的性能指标,进行实时监控和报警。
  • 安全信息和事件管理 (SIEM): 收集安全日志,进行威胁检测和安全分析。
  • 地理位置搜索: 存储和搜索地理位置数据,进行附近的人/地点查询。
  • 业务数据分析: 对业务数据进行多维度分析、报告生成。

1.3 Elasticsearch 与传统数据库的区别

虽然 Elasticsearch 可以存储数据,但它并非传统意义上的数据库。与关系型数据库(如 MySQL)或 NoSQL 数据库(如 MongoDB)相比,Elasticsearch 更专注于搜索和分析,尤其擅长处理非结构化或半结构化数据的全文检索和聚合计算。

  • 数据结构: ES 使用 JSON 文档,比关系型数据库的表结构更灵活。
  • 核心功能: ES 的核心是搜索和分析,数据库的核心是事务处理和结构化数据管理。
  • 索引机制: ES 基于倒排索引(Inverted Index),非常适合全文检索;关系型数据库通常使用 B树索引。
  • ACID 事务: ES 不完全支持 ACID 事务,适合写多读少的场景或对实时一致性要求不那么高的场景。

第二部分:核心概念详解

理解 Elasticsearch 的核心概念是掌握其使用的基础。

2.1 Cluster (集群)

一个 Elasticsearch 集群由一个或多个节点(Node)组成。集群是分布式的基础,它共享所有数据,并提供跨节点的索引和搜索能力。一个集群有一个唯一的名称来标识。

2.2 Node (节点)

一个节点是一个 Elasticsearch 服务的实例。节点是集群的一部分,负责存储数据、参与索引和搜索协调。节点在启动时会通过集群名称加入到对应的集群中。节点有不同的角色(如 master 节点、data 节点、ingest 节点等),但在入门阶段可以先简单理解为它是ES服务的一个运行实例。

2.3 Index (索引)

索引是 Elasticsearch 中存储数据的逻辑空间,类似于传统数据库中的“数据库”或“表”的概念,但其内部结构和机制完全不同。一个索引是相关文档的集合。例如,你可以创建一个索引来存储所有商品信息,另一个索引来存储所有用户订单。每个索引在创建时可以指定其分片和副本的数量。

2.4 Type (类型 – 注意:已废弃)

在 Elasticsearch 7.x 版本之前,一个索引可以包含多个类型(Type),类似于数据库中一个数据库包含多个表。然而,由于同一个索引内的不同类型可能会导致 Lucene 层面的一些问题,Type 概念在 7.x 版本中已被废弃,并在 8.x 版本中完全移除。现在,一个索引通常被设计为只存储一类结构相似的文档。

重要提示: 在使用 Elasticsearch 7.x 及以上版本时,无需考虑 Type,直接在 Index 下操作 Document 即可。通常,一个 Index 就代表一类数据。

2.5 Document (文档)

文档是 Elasticsearch 中存储的最小单元,类似于数据库中的“行”。每个文档是一个 JSON 对象,包含了一系列的键值对。文档是可索引的,意味着其内容可以被搜索。每个文档在索引内有一个唯一的 ID。

2.6 Shard (分片)

分片是将索引分解成更小的、可管理的部分。当一个索引非常大时,单台机器可能无法存储或处理。通过分片,可以将一个大索引的数据分布到集群中的多个节点上。每个分片本身就是一个功能完整的 Lucene 索引。分片可以是主分片(Primary Shard)或副本分片(Replica Shard)。索引在创建时会指定主分片的数量,主分片数量在创建后不能更改。

2.7 Replica (副本)

副本是主分片的拷贝。副本主要有两个作用:
1. 提高可用性: 当主分片所在的节点发生故障时,副本可以提升为新的主分片,保证数据不丢失和服务的连续性。
2. 提高读取性能: 搜索请求可以由主分片或其副本处理,增加搜索的并发能力。

索引在创建时可以指定每个主分片拥有的副本数量,副本数量可以在集群运行中动态调整。

分片与副本的关系示例:

假设创建一个索引,配置 number_of_shards: 3number_of_replicas: 1
这意味着该索引将被分成 3 个主分片(P0, P1, P2)。
每个主分片会有一个副本(R0, R1, R2)。
整个索引在集群中会包含 3 个主分片和 3 个副本分片,总共 6 个分片实例。这些分片会被Elasticsearch自动分配到集群中的不同节点上,以实现负载均衡和高可用。

第三部分:安装与启动 Elasticsearch

我们将介绍本地安装 Elasticsearch 的基本方法。

3.1 安装 Java 环境

Elasticsearch 是基于 Java 开发的,因此需要安装 Java Runtime Environment (JRE) 或 Java Development Kit (JDK)。Elasticsearch 通常对 Java 版本有要求,请查阅对应 ES 版本的官方文档。推荐安装 OpenJDK 11 或更高版本。

可以通过以下命令检查 Java 版本:
bash
java -version

如果未安装或版本不符合要求,请先下载并安装。

3.2 下载 Elasticsearch

访问 Elasticsearch 官方下载页面:https://www.elastic.co/cn/downloads/elasticsearch
选择适合你操作系统的版本进行下载(.tar.gz for Linux/macOS, .zip for Windows)。这里我们以 Linux/macOS 为例。

“`bash

以 7.x 版本为例 (请根据实际需求选择版本)

wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.17.5-linux-x86_64.tar.gz

或者下载最新的 8.x 版本

wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-8.11.3-linux-x86_64.tar.gz

“`

3.3 解压与配置

解压下载的文件:

bash
tar -zxvf elasticsearch-7.17.5-linux-x86_64.tar.gz
cd elasticsearch-7.17.5

进入解压后的目录。重要的目录和文件:
* bin: 启动脚本
* config: 配置文件(elasticsearch.yml, jvm.options 等)
* data: 存储数据
* logs: 存储日志

基本配置 (config/elasticsearch.yml):

这是一个 YAML 格式的配置文件。对于单节点本地运行,通常只需要简单配置或保持默认即可。

“`yaml

集群名称,多个节点加入同一集群需要相同名称

cluster.name: my-application

节点名称

node.name: node-1

数据和日志目录 (默认在安装目录下,生产环境推荐配置到单独的盘)

path.data: /path/to/data

path.logs: /path/to/logs

绑定网络地址,默认只绑定本地回环地址 127.0.0.1

为了外部访问或多节点集群,需要绑定到网络接口地址

network.host: 192.168.1.10 # 特定 IP

network.host: 0.0.0.0 # 绑定所有接口 (仅限安全环境)

network.host: localhost # 仅绑定本地回环 (默认)

HTTP 端口,默认 9200

http.port: 9200

发现节点配置,用于多节点集群发现,单节点可忽略或使用默认

discovery.seed_hosts: [“host1”, “host2”]

对于 8.x 版本,安全配置是默认开启的。入门时可以禁用,但生产环境强烈建议开启。

在 elasticsearch.yml 中添加以下配置禁用安全认证 (不推荐用于生产环境)

xpack.security.enabled: false

xpack.security.transport.ssl.enabled: false

“`

对于单节点本地测试,通常默认配置即可,或者修改 network.host0.0.0.0 或你的局域网 IP 如果需要从其他机器访问。请注意:在生产环境中禁用安全认证是非常危险的行为。

3.4 启动 Elasticsearch

在 Elasticsearch 根目录下,执行启动脚本:

bash
./bin/elasticsearch

如果一切正常,你会在控制台看到启动日志。等待日志输出类似 "message":"started" 的信息,表示节点已成功启动。

后台启动 (Linux/macOS):

bash
./bin/elasticsearch -d

日志输出到 logs 目录下。

3.5 验证安装

打开浏览器或使用 curl 命令,访问 Elasticsearch 的 HTTP 接口(默认端口 9200):

bash
curl http://localhost:9200

如果看到一个包含集群信息、节点信息、版本号等 JSON 响应,说明 Elasticsearch 已经成功运行。

json
{
"name" : "your-node-name",
"cluster_name" : "elasticsearch",
"cluster_uuid" : "...",
"version" : {
"number" : "7.17.5", // 或 8.x 版本
"build_flavor" : "default",
"build_type" : "tar",
"build_hash" : "...",
"build_date" : "...",
"build_snapshot" : false,
"lucene_version" : "8.11.1",
"minimum_wire_compatibility_version" : "6.8.0",
"minimum_index_compatibility_version" : "6.0.0-beta1"
},
"tagline" : "You Know, for Search"
}

安装 Kibana (可选但强烈推荐):

Kibana 是与 Elasticsearch 配套的可视化和管理工具。安装对应版本的 Kibana,修改其配置文件 (config/kibana.yml) 中的 elasticsearch.hosts 指向你的 Elasticsearch 节点地址,然后启动 Kibana。通过浏览器访问 Kibana 的 Web 界面(默认端口 5601),可以在 Dev Tools 中方便地执行 Elasticsearch API 命令。

第四部分:基本数据操作 (CRUD)

Elasticsearch 提供 RESTful API 进行数据操作。我们将使用 curl 命令作为示例,你在 Kibana 的 Dev Tools 中也可以方便地执行这些命令。

4.1 创建/索引文档 (Index Document)

索引文档是将数据存储到 Elasticsearch 中的过程。你可以指定文档 ID,也可以让 ES 自动生成。

自动生成 ID: 使用 POST 请求到 /{index_name}/_doc/ 路径。

“`bash

索引一个用户文档到 ‘users’ 索引

curl -X POST “localhost:9200/users/_doc/” -H “Content-Type: application/json” -d’
{
“username”: “zhangsan”,
“age”: 30,
“city”: “Beijing”,
“join_date”: “2023-01-15”
}

``
响应会包含索引名称、自动生成的文档 ID (
_id) 和版本号 (_version`)。

指定文档 ID: 使用 PUT 请求到 /{index_name}/_doc/{document_id} 路径。如果该 ID 已存在,会替换原有文档;如果不存在,则创建新文档。

“`bash

索引一个 ID 为 ‘1’ 的商品文档到 ‘products’ 索引

curl -X PUT “localhost:9200/products/_doc/1” -H “Content-Type: application/json” -d’
{
“product_name”: “Laptop”,
“brand”: “Dell”,
“price”: 8500.00,
“in_stock”: true,
“tags”: [“electronics”, “computer”]
}

“`

使用 _create 强制创建 (如果 ID 已存在则失败): 使用 PUT 请求到 /{index_name}/_create/{document_id} 路径。

“`bash

尝试创建一个 ID 为 ‘1’ 的商品文档,如果已存在则失败

curl -X PUT “localhost:9200/products/_create/1” -H “Content-Type: application/json” -d’
{
“product_name”: “Laptop”,
“brand”: “Dell”,
“price”: 8500.00,
“in_stock”: true,
“tags”: [“electronics”, “computer”]
}

“`

4.2 获取文档 (Get Document)

使用 GET 请求到 /{index_name}/_doc/{document_id} 路径来获取指定 ID 的文档。

“`bash

获取 users 索引下 ID 为 ‘auto_generated_id’ 的文档 (替换为实际ID)

curl -X GET “localhost:9200/users/_doc/auto_generated_id”

获取 products 索引下 ID 为 ‘1’ 的文档

curl -X GET “localhost:9200/products/_doc/1”
``
响应会包含文档的索引、ID、版本以及
_source字段,_source就是原始的 JSON 文档内容。found: true` 表示文档存在。

4.3 更新文档 (Update Document)

更新文档有两种主要方式:全量替换和部分更新。

全量替换 (Full Replacement): 使用 PUT 请求到 /index_name/_doc/{document_id},并提供完整的文档内容。这会删除旧文档,然后索引新文档(版本号会增加)。

“`bash

全量更新 ID 为 ‘1’ 的商品文档

curl -X PUT “localhost:9200/products/_doc/1” -H “Content-Type: application/json” -d’
{
“product_name”: “Gaming Laptop”, # 名称改变
“brand”: “Dell”,
“price”: 9999.99, # 价格改变
“in_stock”: false, # 状态改变
“tags”: [“electronics”, “computer”, “gaming”] # 标签改变
}

“`

部分更新 (Partial Update): 使用 POST 请求到 /{index_name}/_update/{document_id} 路径,并在请求体中使用 doc 字段指定要修改的字段,或者使用 script 字段执行脚本更新。部分更新不会替换整个文档,只会修改指定字段,效率更高。

使用 doc 字段:

“`bash

部分更新 ID 为 ‘1’ 的商品文档,只修改价格和库存状态

curl -X POST “localhost:9200/products/_update/1” -H “Content-Type: application/json” -d’
{
“doc”: {
“price”: 9500.00,
“in_stock”: true
}
}

“`

使用 script 字段:适用于更复杂的更新逻辑,例如对字段进行计算或增减。

“`bash

使用脚本将 ID 为 ‘1’ 的商品价格降低 100

curl -X POST “localhost:9200/products/_update/1” -H “Content-Type: application/json” -d’
{
“script”: {
“source”: “ctx._source.price -= 100”,
“lang”: “painless” # Painless 是 Elasticsearch 推荐的脚本语言
}
}

“`

4.4 删除文档 (Delete Document)

使用 DELETE 请求到 /{index_name}/_doc/{document_id} 路径。

“`bash

删除 products 索引下 ID 为 ‘1’ 的文档

curl -X DELETE “localhost:9200/products/_doc/1”
``
响应会指示操作是否成功 (
result: deleted`)。

4.5 批量操作 (Bulk API)

Elasticsearch 提供了 _bulk API 来执行多个索引、创建、更新或删除操作,这比单独发送每个请求效率高得多。请求体格式比较特殊,是 newline-delimited JSON (NDJSON)。

每个操作由两行组成:一行是操作元数据(operation metadata),指定操作类型 (index, create, update, delete)、索引和文档 ID;另一行是文档本身(对于 indexcreate)或更新信息(对于 update)。delete 操作不需要文档内容。

bash
curl -X POST "localhost:9200/_bulk" -H "Content-Type: application/json" -d'
{"index": {"_index": "users", "_id": "2"}}
{"username": "lisi", "age": 25, "city": "Shanghai", "join_date": "2023-03-10"}
{"create": {"_index": "users", "_id": "3"}}
{"username": "wangwu", "age": 35, "city": "Guangzhou", "join_date": "2022-05-20"}
{"update": {"_index": "products", "_id": "1"}}
{"doc": {"price": 9000.00}}
{"delete": {"_index": "users", "_id": "auto_generated_id"}}
' # 注意:最后一行必须是换行符

_bulk API 是导入大量数据时的首选方式。

第五部分:强大的搜索能力

搜索是 Elasticsearch 的核心功能。它提供了丰富灵活的查询语言——Query DSL (Domain Specific Language),基于 JSON 构建。

5.1 基本搜索 _search

使用 GETPOST 请求到 /{index_name}/_search 路径。GET 请求可以将查询参数放在 URL 中,POST 请求则将查询体放在请求体中。对于复杂的查询,通常使用 POST

“`bash

搜索 users 索引下的所有文档 (match_all query)

curl -X GET “localhost:9200/users/_search” -H “Content-Type: application/json” -d’
{
“query”: {
“match_all”: {}
}
}

``
响应包含匹配到的总数 (
hits.total)、耗时 (took) 以及匹配到的文档列表 (hits.hits)。每个文档在列表中包含索引、ID、得分 (_score) 和源文档 (_source`)。

5.2 Query DSL 核心结构

Query DSL 通常包含在 query 字段中,其内部可以是各种类型的查询。

json
{
"query": {
"YOUR_QUERY_TYPE": {
// Query parameters
}
},
// Optional parameters like size, from, sort, _source filtering, etc.
"size": 10, // 返回结果数量,默认10
"from": 0, // 分页起始位置
"sort": [ // 排序
{ "field_name": "order" }
],
"_source": ["field1", "field2"] // 只返回指定字段
}

5.3 常用查询类型 (Query Types)

  • Match Query: 执行全文搜索,会对查询词进行分词处理。

    “`json

    搜索 products 索引中 product_name 字段包含 “Laptop” 的文档

    {
    “query”: {
    “match”: {
    “product_name”: “Laptop”
    }
    }
    }
    ``
    默认情况下,
    match` 查询会将 “Laptop” 分词后(例如,如果使用 standard analyzer,”Laptop” 就是一个词),去倒排索引中查找包含该词的文档。

  • Term Query: 精确匹配,不会对查询词进行分词。适用于关键字、数字、日期等精确值查找。通常用于非文本字段或 keyword 类型的字段。

    “`json

    搜索 users 索引中 city 字段精确匹配 “Beijing” 的文档

    {
    “query”: {
    “term”: {
    “city.keyword”: “Beijing” # 注意:text字段需要使用 .keyword 后缀进行term查询
    }
    }
    }
    “`

  • Range Query: 查找某一范围内的文档。适用于数字和日期字段。

    “`json

    搜索 products 索引中 price 在 8000 到 10000 之间的文档 (包含边界)

    {
    “query”: {
    “range”: {
    “price”: {
    “gte”: 8000,
    “lte”: 10000
    }
    }
    }
    }

    搜索 users 索引中 join_date 在 2023 年之后 (不包含) 的文档

    {
    “query”: {
    “range”: {
    “join_date”: {
    “gt”: “2023-01-01”
    }
    }
    }
    }
    ``
    范围操作符:
    gt(大于),gte(大于等于),lt(小于),lte` (小于等于)。

  • Bool Query: 组合多个查询条件,类似于 SQL 的 AND, OR, NOT。包含以下子句:

    • must: 必须匹配,相当于 AND。会计算得分。
    • filter: 必须匹配,相当于 AND。不会计算得分,结果可缓存,适合用于过滤。
    • should: 应该匹配,相当于 OR。至少满足一个 should 子句,文档就会被返回(除非有 must 或 filter)。会计算得分。
    • must_not: 必须不匹配,相当于 NOT。不会计算得分。

    filter 子句是提高搜索性能的关键,因为它们不会计算相关性得分 (_score),并且结果易于缓存。

    “`json

    搜索 products 索引中 product_name 包含 “Laptop”,并且 price 小于 10000,并且 in_stock 为 true 的文档

    {
    “query”: {
    “bool”: {
    “must”: [
    {
    “match”: {
    “product_name”: “Laptop”
    }
    }
    ],
    “filter”: [ # 使用 filter 进行精确过滤和范围过滤,不影响得分
    {
    “range”: {
    “price”: {
    “lt”: 10000
    }
    }
    },
    {
    “term”: {
    “in_stock”: true
    }
    }
    ]
    }
    }
    }
    “`

5.4 全文搜索与 Mapping、Analyzer

Elasticsearch 的全文搜索能力很大程度上依赖于 MappingAnalyzer

  • Mapping (映射): 定义了索引中文档及其字段的结构和数据类型。类似于数据库表结构定义。Elasticsearch 默认支持动态映射,即在你索引第一个文档时,它会尝试猜测字段类型并创建映射。但这并不总是最优的,特别对于文本字段。为了精确控制搜索行为,通常需要手动创建或修改映射。

    • text: 适合全文检索的字段,会进行分词处理。
    • keyword: 适合精确值匹配的字段,不会分词。
    • integer, float, long, double: 数字类型。
    • boolean: 布尔类型。
    • date: 日期类型。
    • object: JSON 对象。
    • nested: 特殊的对象类型,用于独立索引对象数组中的每个对象。

    创建索引时指定 Mapping:

    bash
    curl -X PUT "localhost:9200/my_documents" -H "Content-Type: application/json" -d'
    {
    "mappings": {
    "properties": {
    "title": {
    "type": "text",
    "analyzer": "ik_smart" # 指定中文分词器 (需要安装插件)
    },
    "content": {
    "type": "text"
    },
    "publish_date": {
    "type": "date"
    },
    "tags": {
    "type": "keyword"
    }
    }
    }
    }
    '

  • Analyzer (分析器): 用于处理文本字段,包括分词(Tokenization)、转换(如转小写、去除停用词)等。 Elasticsearch 有内置的分析器(如 standard 分析器),也支持安装插件(如 ik-analyzer 用于中文分词)或自定义分析器。

    • standard 分析器:基于 Unicode Text Segmentation 算法,适用于多种语言,但对中文支持不佳(单个汉字作为一个词)。
    • 中文分词器(如 ik-analyzer):能正确将中文文本切分成有意义的词语。安装 ik-analyzer 插件后,可以在 Mapping 中指定 analyzer: "ik_smart"analyzer: "ik_max_word"

    理解 Mapping 和 Analyzer 对于构建高效准确的搜索至关重要。不指定时,Elasticsearch 会尝试猜测并使用默认设置。

5.5 高亮 (Highlighting)

在搜索结果中高亮显示匹配的关键词,可以帮助用户快速定位相关信息。

“`json

搜索 products 索引中 product_name 包含 “Laptop”,并高亮显示匹配词

{
“query”: {
“match”: {
“product_name”: “Laptop”
}
},
“highlight”: {
“fields”: {
“product_name”: {}
}
}
}
``
响应中的
hits.hits数组会包含highlight字段,其中是要高亮的字段及其带有 HTML 标签(默认是`)的内容。

第六部分:常用的高级特性初步

6.1 Aggregations (聚合)

聚合是 Elasticsearch 强大的分析功能。它允许你对搜索结果进行分组、计算统计指标(如总和、平均值、最大值、最小值、计数等),实现数据分析和商业智能。类似于 SQL 中的 GROUP BY 和各种聚合函数(COUNT, SUM, AVG, MIN, MAX)。

聚合有不同的类型,如:
* Bucket Aggregations: 按某些标准(如字段值、范围、日期间隔)将文档分组到不同的“桶”中。常用的有 terms (按字段值分组), range (按范围分组), date_histogram (按日期间隔分组)。
* Metric Aggregations: 对桶内的文档计算度量指标。常用的有 count, sum, avg, min, max, stats

聚合通常与查询结合使用,先通过查询过滤出感兴趣的文档集合,然后对这个集合进行聚合分析。

“`json

搜索 products 索引,并按 brand 字段进行分组,计算每组的商品数量

{
“size”: 0, # 不返回搜索结果,只返回聚合结果
“aggs”: { # 定义聚合
“products_by_brand”: { # 聚合名称 (自定义)
“terms”: { # 聚合类型:terms aggregation (按字段值分组)
“field”: “brand.keyword”, # 聚合字段 (keyword 类型适合精确分组)
“size”: 10 # 返回前10个品牌
}
}
}
}
``
响应会包含
aggregations字段,其中是products_by_brand` 聚合的结果,列出每个品牌及其文档数量。

你也可以嵌套聚合,例如先按品牌分组,再在每个品牌内按价格范围分组。

“`json

按 brand 分组,并在每个品牌内按 price 分组 (低于5000, 5000-10000, 高于10000)

{
“size”: 0,
“aggs”: {
“products_by_brand”: {
“terms”: {
“field”: “brand.keyword”
},
“aggs”: { # 嵌套聚合
“price_ranges”: {
“range”: {
“field”: “price”,
“ranges”: [
{ “to”: 5000 },
{ “from”: 5000, “to”: 10000 },
{ “from”: 10000 }
]
}
}
}
}
}
}
“`

聚合是 Elasticsearch 实现实时数据仪表盘和报表的基础,在 Kibana 中广泛使用。

6.2 索引管理

Elasticsearch 提供了丰富的 API 来管理索引,如创建、删除、查看设置和映射、打开/关闭索引等。

“`bash

查看所有索引

curl -X GET “localhost:9200/_cat/indices?v” # 使用 _cat API 获取简洁列表

查看特定索引的设置和映射

curl -X GET “localhost:9200/my_documents?pretty” # pretty 参数美化输出
“`

6.3 集群管理

通过 _cat API 可以方便地查看集群状态、节点信息、分片分布等。

“`bash

查看集群健康状态 (green: 健康, yellow: 主分片正常但有副本未分配, red: 有主分片丢失)

curl -X GET “localhost:9200/_cat/health?v”

查看节点列表

curl -X GET “localhost:9200/_cat/nodes?v”

查看分片分布

curl -X GET “localhost:9200/_cat/shards?v”
“`

第七部分:实战案例:构建一个简单的文章搜索系统

假设我们要构建一个文章搜索系统,包含文章标题、内容、作者和发布日期。

步骤 1:设计 Mapping

我们需要一个索引来存储文章。标题和内容需要全文检索,作者需要精确匹配,发布日期需要按范围查询和排序。同时,为了支持中文搜索,我们将为标题和内容字段配置中文分词器(假设已安装并配置 ik-analyzer 插件)。

“`bash

创建 articles 索引并定义 Mapping

curl -X PUT “localhost:9200/articles” -H “Content-Type: application/json” -d’
{
“settings”: {
“number_of_shards”: 1, # 入门示例,单节点够用
“number_of_replicas”: 0 # 入门示例,不配置副本
},
“mappings”: {
“properties”: {
“title”: {
“type”: “text”,
“analyzer”: “ik_smart”
},
“content”: {
“type”: “text”,
“analyzer”: “ik_smart”
},
“author”: {
“type”: “keyword” # 作者名精确匹配
},
“publish_date”: {
“type”: “date”
}
}
}
}

“`

步骤 2:索引示例文档

使用 _bulk API 批量导入几篇示例文章。

bash
curl -X POST "localhost:9200/_bulk" -H "Content-Type: application/json" -d'
{"index": {"_index": "articles", "_id": "1"}}
{"title": "Elasticsearch 入门指南", "content": "这是一篇关于 Elasticsearch 基础概念和入门使用的文章。", "author": "张三", "publish_date": "2023-01-10"}
{"index": {"_index": "articles", "_id": "2"}}
{"title": "深入理解 Elasticsearch 查询 DSL", "content": "本文详细介绍了 Elasticsearch 的查询 DSL,包括各种查询类型和组合方式。", "author": "李四", "publish_date": "2023-03-15"}
{"index": {"_index": "articles", "_id": "3"}}
{"title": "Elasticsearch 聚合功能实战", "content": "通过实战案例,学习如何使用 Elasticsearch 的聚合功能进行数据分析。", "author": "张三", "publish_date": "2023-05-20"}
{"index": {"_index": "articles", "_id": "4"}}
{"index": {"_index": "articles", "_id": "5"}}
{"title": "使用 Kibana 进行日志分析", "content": "介绍如何利用 Kibana 配合 Elasticsearch 进行日志收集、可视化和分析。", "author": "王五", "publish_date": "2023-06-01"}
'

步骤 3:执行搜索

简单搜索: 搜索标题或内容中包含 “Elasticsearch” 的文章。

bash
curl -X GET "localhost:9200/articles/_search" -H "Content-Type: application/json" -d'
{
"query": {
"multi_match": { # multi_match 可以在多个字段中搜索
"query": "Elasticsearch",
"fields": ["title", "content"]
}
}
}
'

组合搜索: 搜索标题或内容包含 “Elasticsearch”,并且作者是 “张三” 的文章。

bash
curl -X GET "localhost:9200/articles/_search" -H "Content-Type: application/json" -d'
{
"query": {
"bool": {
"must": [
{
"multi_match": {
"query": "Elasticsearch",
"fields": ["title", "content"]
}
}
],
"filter": [ # 作者是精确匹配,使用 filter 性能更好
{
"term": {
"author.keyword": "张三"
}
}
]
}
}
}
'

带过滤和排序的搜索: 搜索标题或内容包含 “Elasticsearch”,发布日期在 2023 年 3 月 1 日之后的文章,并按发布日期降序排列。

bash
curl -X GET "localhost:9200/articles/_search" -H "Content-Type: application/json" -d'
{
"query": {
"bool": {
"must": [
{
"multi_match": {
"query": "Elasticsearch",
"fields": ["title", "content"]
}
}
],
"filter": [
{
"range": {
"publish_date": {
"gt": "2023-03-01"
}
}
}
]
}
},
"sort": [ # 按发布日期降序排序
{
"publish_date": "desc"
}
],
"highlight": { # 添加高亮
"fields": {
"title": {},
"content": {}
}
}
}
'

步骤 4:进行聚合分析

统计每位作者发布的文章数量。

bash
curl -X GET "localhost:9200/articles/_search" -H "Content-Type: application/json" -d'
{
"size": 0, # 只返回聚合结果
"aggs": {
"articles_by_author": { # 聚合名称
"terms": {
"field": "author.keyword" # 按作者进行分组
}
}
}
}
'

结果将显示每位作者(张三、李四、王五)及其对应的文章计数。

这个简单的实战案例展示了如何结合 Mapping、索引、查询和聚合来构建一个基本的搜索和分析系统。在实际应用中,你可能还需要考虑更复杂的查询逻辑、分词器的选择、性能优化、集群扩展等方面的问题。

第八部分:进阶学习与资源

  • 官方文档: Elasticsearch 的官方文档非常详细和权威,是最好的学习资源。
  • Elastic Stack: 深入了解与 Elasticsearch 集成的其他组件,如 Kibana (可视化), Logstash (数据采集处理), Beats (轻量级数据采集器)。
  • 插件生态: 探索各种有用的插件,如各种分析器插件、安全插件等。
  • 性能优化: 学习如何优化查询性能、索引性能,调整集群参数。
  • 集群管理与运维: 学习如何监控集群、处理故障、进行扩容和升级。
  • Elastic Cloud: 了解 Elastic 官方提供的云服务,可以省去自行运维的麻烦。

结论

Elasticsearch 是一个功能强大、灵活且易于扩展的分布式搜索和分析引擎。通过本文的学习,你应该对 Elasticsearch 的核心概念、安装使用、基本数据操作以及强大的搜索和分析能力有了初步的了解。从入门到精通 Elasticsearch 需要持续的学习和实践,但掌握了这些基础知识,你已经迈出了构建高效搜索和数据分析应用的第一步。

希望这篇详细的教程对你有所帮助!祝你在 Elasticsearch 的探索之路上一帆风顺!


发表评论

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

滚动至顶部