Elasticsearch (ES) 教程:从安装到高级搜索
Elasticsearch (ES) 教程:从安装到高级搜索
Elasticsearch(简称 ES)是一个基于 Apache Lucene 的开源、分布式、RESTful 风格的搜索和数据分析引擎。它能够近实时地存储、搜索和分析海量数据。Elasticsearch 以其高性能、可扩展性和易用性而闻名,广泛应用于日志分析、全文搜索、安全情报、业务分析和基础设施监控等领域。
本教程将带你从零开始,逐步深入了解 Elasticsearch,涵盖安装、配置、基本概念、数据操作、各种搜索技术以及高级特性。
1. 安装与配置
1.1. 环境准备
- Java 环境: Elasticsearch 需要 Java 8 或更高版本。 建议使用 OpenJDK 或 Oracle JDK。 确保
JAVA_HOME
环境变量已正确设置。 - 操作系统: Elasticsearch 支持 Linux、macOS 和 Windows。 本教程主要以 Linux (例如 Ubuntu) 为例,其他操作系统上的安装过程类似。
- 下载: 从官网下载地址进行下载: https://www.elastic.co/cn/downloads/elasticsearch
1.2. 安装步骤 (Linux)
-
下载 Elasticsearch:
bash
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-8.x.x-linux-x86_64.tar.gz (替换为最新版本) -
解压:
bash
tar -xzf elasticsearch-8.x.x-linux-x86_64.tar.gz -
进入目录:
bash
cd elasticsearch-8.x.x -
启动 Elasticsearch:
bash
./bin/elasticsearch
第一次启动会生成密码, 务必记下来. -
后台运行(可选):
bash
./bin/elasticsearch -d -
验证安装:
在浏览器中访问http://localhost:9200
,你应该会看到一个 JSON 响应,其中包含 Elasticsearch 集群的信息。
1.3. 基本配置 (elasticsearch.yml)
Elasticsearch 的主要配置文件是 config/elasticsearch.yml
。以下是一些常见的配置项:
cluster.name
: 集群名称,同一集群中的节点应具有相同的名称。node.name
: 节点名称,默认为机器的主机名。path.data
: 数据存储路径,默认为data
目录。path.logs
: 日志存储路径,默认为logs
目录。network.host
: 绑定的 IP 地址,默认为127.0.0.1
(仅本地访问)。要允许远程访问,可以设置为0.0.0.0
。http.port
: HTTP 端口,默认为9200
。discovery.seed_hosts
: 集群发现的主机列表 (用于多节点集群)。例如:["192.168.1.10", "192.168.1.11"]
cluster.initial_master_nodes
: 初始主节点列表 (用于多节点集群)。例如:["node-1", "node-2"]
重要提示: 修改配置文件后,需要重启 Elasticsearch 才能生效。
1.4. 安装 Kibana (可选)
Kibana 是 Elasticsearch 的一个配套工具,提供了一个强大的 Web 界面,用于数据可视化、探索、管理和监控 Elasticsearch 集群。
-
下载 Kibana:
bash
wget https://artifacts.elastic.co/downloads/kibana/kibana-8.x.x-linux-x86_64.tar.gz (替换为最新版本, 且与 ES 版本对应) -
解压:
bash
tar -xzf kibana-8.x.x-linux-x86_64.tar.gz -
进入目录:
bash
cd kibana-8.x.x -
启动 Kibana
bash
./bin/kibana -
访问 Kibana:
在浏览器中访问http://localhost:5601
。
2. 核心概念
在深入使用 Elasticsearch 之前,理解以下核心概念至关重要:
- 集群 (Cluster): 一个或多个 Elasticsearch 节点组成的集合,共同存储和处理数据。
- 节点 (Node): 一个 Elasticsearch 实例,通常运行在一台服务器上。
- 索引 (Index): 类似于关系型数据库中的“数据库”,用于存储相关的文档。索引是文档的集合。
- 类型 (Type): 在 Elasticsearch 7.x 及之前的版本中,类型用于对索引中的文档进行逻辑分组 (类似于数据库中的“表”)。从 Elasticsearch 8.x 开始,类型已被移除。
- 文档 (Document): Elasticsearch 中存储的基本数据单元,以 JSON 格式表示。类似于关系型数据库中的“行”。
- 字段 (Field): 文档中的一个属性,包含名称和值。类似于关系型数据库中的“列”。
- 映射 (Mapping): 定义了索引中字段的类型、存储方式和分析方式。类似于关系型数据库中的“表结构”。
- 分片 (Shard): 索引可以被水平分割成多个分片,每个分片都是一个独立的 Lucene 索引。分片可以提高性能和可扩展性。
- 副本 (Replica): 每个分片可以有零个或多个副本。副本可以提高可用性和搜索性能。
3. 数据操作 (CRUD)
Elasticsearch 提供了 RESTful API 来进行各种数据操作,包括创建、读取、更新和删除文档 (CRUD)。
3.1. 创建索引
json
PUT /my_index
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 1
},
"mappings": {
"properties": {
"title": { "type": "text" },
"content": { "type": "text" },
"timestamp": { "type": "date" }
}
}
}
PUT /my_index
: 创建名为my_index
的索引。settings
: 索引设置,包括分片数和副本数。mappings
: 定义字段的映射。properties
: 字段列表。type
: 字段类型 (例如text
,keyword
,date
,integer
,boolean
等)。
3.2. 插入文档 (索引文档)
```json
POST /my_index/_doc/1
{
"title": "Elasticsearch Tutorial",
"content": "This is a comprehensive guide to Elasticsearch.",
"timestamp": "2023-10-27T10:00:00"
}
POST /my_index/_doc
{
"title": "Another Document",
"content": "This is another document in the index.",
"timestamp": "2023-10-27T11:00:00"
}
```
POST /my_index/_doc/1
: 向my_index
索引添加一个文档,指定 ID 为1
。POST /my_index/_doc
: 向my_index
索引添加一个文档,Elasticsearch 会自动生成一个唯一的 ID。
3.3. 获取文档
json
GET /my_index/_doc/1
GET /my_index/_doc/1
: 获取my_index
索引中 ID 为1
的文档。
3.4. 更新文档
json
POST /my_index/_update/1
{
"doc": {
"content": "This is an updated guide to Elasticsearch."
}
}
POST /my_index/_update/1
更新 ID 为1 的文档doc
: 包含要更新的字段。
3.5. 删除文档
json
DELETE /my_index/_doc/1
DELETE /my_index/_doc/1
: 删除my_index
索引中 ID 为1
的文档。
3.6. 删除索引
json
DELETE /my_index
* DELETE /my_index
: 删除名为 my_index
的索引。
4. 搜索
Elasticsearch 的核心功能是搜索。它提供了强大的查询 DSL (Domain Specific Language),允许你构建各种复杂的查询。
4.1. 基本搜索
json
GET /my_index/_search
{
"query": {
"match_all": {}
}
}
match_all
: 匹配所有文档。
json
GET /my_index/_search
{
"query": {
"match": {
"content": "guide"
}
}
}
match
: 在content
字段中搜索包含 "guide" 的文档。
4.2. 常用查询类型
-
term
查询: 精确匹配,不进行分词。
json
{
"query": {
"term": {
"title.keyword": "Elasticsearch Tutorial"
}
}
} -
terms
查询: 匹配多个精确值。
json
{
"query": {
"terms": {
"tags": ["elasticsearch", "tutorial"]
}
}
} -
range
查询: 范围查询。
json
{
"query": {
"range": {
"timestamp": {
"gte": "2023-10-27T00:00:00",
"lte": "2023-10-27T23:59:59"
}
}
}
} -
exists
查询: 检查字段是否存在。
json
{
"query": {
"exists": {
"field": "author"
}
}
} -
bool
查询: 组合多个查询。
json
{
"query": {
"bool": {
"must": [
{ "match": { "title": "elasticsearch" } },
{ "match": { "content": "tutorial" } }
],
"must_not": [
{ "term": { "status": "draft" } }
],
"should": [
{ "term": { "featured": true } }
],
"filter": {
"range": {
"timestamp": {
"gte": "now-1d/d"
}
}
}
}
}
}must
: 必须匹配(AND)。must_not
: 必须不匹配 (NOT)。should
: 应该匹配 (OR),可以提高相关性得分。filter
: 过滤,不参与算分.
-
wildcard
查询: 通配符查询,*
代表多个字符,?
代表一个字符
json
{
"query": {
"wildcard": {
"user.id": {
"value": "ki*y",
"boost": 1.0,
"rewrite": "constant_score"
}
}
}
}
4.3. 过滤 (Filter)
过滤与查询类似,但不计算相关性得分,因此执行速度更快。过滤通常用于结构化数据的筛选。
json
GET /my_index/_search
{
"query": {
"bool": {
"must": {
"match": { "content": "guide" }
},
"filter": {
"term": { "status": "published" }
}
}
}
}
在上面的例子, filter
不会影响搜索结果的排序。
4.4. 排序 (Sorting)
json
GET /my_index/_search
{
"query": {
"match_all": {}
},
"sort": [
{ "timestamp": { "order": "desc" } }
]
}
sort
: 指定排序字段和顺序 (asc
或desc
)。
4.5. 分页 (Pagination)
json
GET /my_index/_search
{
"query": {
"match_all": {}
},
"from": 10,
"size": 20
}
from
: 起始位置 (偏移量)。size
: 返回的文档数量。
4.6 全文检索
Elasticsearch 基于 Lucene 的倒排索引,对全文检索有非常好的支持。以下是全文检索中常用的概念:
- 分词 (Analysis): 将文本分解成一系列的词条 (terms) 的过程。Elasticsearch 内置了多种分词器,也可以自定义分词器。
- 词干提取 (Stemming): 将单词还原为词根形式 (例如,"running" -> "run")。
- 停用词 (Stop words): 常见的、无实际意义的词 (例如,"the", "a", "is"),通常在索引和搜索时会被忽略。
5. 高级特性
5.1. 聚合 (Aggregations)
聚合用于对数据进行统计和分析。Elasticsearch 提供了多种聚合类型,例如:
terms
聚合: 按字段值分组。avg
聚合: 计算平均值。sum
聚合: 计算总和。min
聚合: 计算最小值。max
聚合: 计算最大值。date_histogram
聚合: 按日期范围分组。
json
GET /my_index/_search
{
"size": 0,
"aggs": {
"group_by_status": {
"terms": {
"field": "status.keyword"
}
},
"average_price": {
"avg": {
"field": "price"
}
}
}
}
上面例子中, size:0
表示不返回文档本身, aggs
定义了两个聚合.
5.2. 索引别名 (Aliases)
索引别名可以指向一个或多个索引,类似于数据库中的视图。别名可以简化索引管理,实现零停机时间的数据迁移和索引重建。
json
POST /_aliases
{
"actions": [
{ "add": { "index": "my_index_v1", "alias": "my_index" } },
{ "remove": { "index": "my_index_v1", "alias": "my_old_index" } }
]
}
5.3. 滚动查询
对于需要检索大量数据的场景,可以使用滚动查询(Scroll API)。滚动查询会创建一个快照,并允许你分批次地获取结果。
json
GET /my_index/_search?scroll=1m
{
"size": 100,
"query": {
"match_all" : {}
}
}
首次查询后, 会得到一个 _scroll_id
, 使用 _scroll_id
进行后续查询:
json
POST /_search/scroll
{
"scroll" : "1m",
"scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAD4WYm9laVYtZndUQlNsdDcwakFMNjU1QQ=="
}
5.4 批量操作
为了提高效率, 可以使用批量操作, 一次执行多个请求。
```json
POST _bulk
{ "index" : { "_index" : "test", "_id" : "1" } }
{ "field1" : "value1" }
{ "delete" : { "_index" : "test", "_id" : "2" } }
{ "create" : { "_index" : "test", "_id" : "3" } }
{ "field1" : "value3" }
{ "update" : {"_id" : "1", "_index" : "test"} }
{ "doc" : {"field2" : "value2"} }
```
6. 总结
本教程详细介绍了 Elasticsearch 的安装、配置、核心概念、数据操作、搜索技术和高级特性。 通过学习本教程,你应该能够:
- 安装和配置 Elasticsearch。
- 理解 Elasticsearch 的核心概念。
- 使用 RESTful API 进行数据操作。
- 构建各种类型的查询。
- 使用聚合进行数据分析。
- 了解并运用一些高级功能。
Elasticsearch 是一个功能强大且灵活的工具,可以应用于各种场景。 随着你对 Elasticsearch 的深入了解和实践,你将能够更好地利用它来解决实际问题。 建议进一步阅读 Elasticsearch 官方文档,并进行更多的实践操作,以掌握更高级的用法和技巧。