Elasticsearch 入门教程:从零开始掌握 – wiki基地


Elasticsearch 入门教程:从零开始,解锁数据搜索的无限可能

前言:数据洪流时代的利器

在当今数据爆炸的时代,无论是企业内部的日志分析、电商平台的商品搜索、社交媒体的实时动态,还是物联网设备的传感器数据,我们都面临着海量数据的存储、检索和分析挑战。传统的关系型数据库在处理复杂、实时、高并发的全文搜索和聚合分析时往往显得力不从心。这时,一个强大的分布式搜索与分析引擎应运而生——它就是 Elasticsearch

Elasticsearch(简称ES)是一个基于Apache Lucene™的开源、分布式、RESTful风格的搜索和分析引擎。它以其卓越的搜索速度、强大的分析能力、简单的RESTful API和出色的可扩展性,迅速成为大数据领域的热门技术。本教程将带领您从零开始,一步步掌握Elasticsearch,解锁数据搜索的无限可能。

第一章:Elasticsearch 世界观:核心概念剖析

在深入学习ES的操作之前,理解其背后的核心概念至关重要。这些概念是构建ES世界的基石。

1. 近实时 (Near Real-time, NRT)

Elasticsearch 是一个近实时(NRT)的搜索平台。这意味着从索引文档到可搜索文档之间会有一个短暂的延迟(通常是秒级)。这个延迟是由于ES为了优化写入性能而进行的一些内部操作(如刷新/提交)造成的。

2. 集群 (Cluster)

Elasticsearch 的核心是集群。一个集群由一个或多个节点组成,这些节点协同工作,共同存储所有数据并提供搜索和分析功能。集群通过一个唯一的名称(cluster.name)来标识,节点之间通过这个名称发现并加入集群。

3. 节点 (Node)

节点是集群中的一个单一服务器实例。每个节点都存储数据,并参与集群的索引和搜索能力。节点可以配置为不同的类型,承担不同的职责:
* 主节点 (Master Node):负责管理集群范围内的操作,如创建/删除索引、跟踪哪些节点是集群的一部分、以及决定分片如何分配给节点。一个健康的集群必须有一个主节点。
* 数据节点 (Data Node):存储索引数据,并执行数据相关的操作,如CRUD(创建、读取、更新、删除)以及搜索和聚合。
* 摄入节点 (Ingest Node):可以对文档进行预处理,例如转换、丰富或规范化数据,然后再将其索引到ES中。
* 协调节点 (Coordinating Node):当一个请求发送到一个非数据或非主节点时,这个节点会作为一个协调节点,将请求转发给适当的数据节点,然后收集这些节点的响应并返回给客户端。所有节点都可以充当协调节点。

4. 索引 (Index)

索引是Elasticsearch中存储相关文档的集合。可以将其类比为关系型数据库中的“数据库(Database)”。一个ES集群可以包含多个索引。例如,您可以有一个 logs 索引存储日志数据,一个 products 索引存储商品信息。索引名称必须是小写。

5. 文档 (Document)

文档是Elasticsearch中可被索引的基本信息单元。可以将其类比为关系型数据库中的“一行(Row)”。每个文档都是一个JSON对象,包含一个或多个字段(Field)。ES存储的是JSON格式的文档。每个文档都有一个唯一的ID。

6. 字段 (Field)

字段是文档中的键值对。可以将其类比为关系型数据库中的“列(Column)”。例如,一个商品文档可能有 namepricedescription 等字段。

7. 映射 (Mapping)

映射定义了文档及其字段的结构、数据类型以及ES如何处理它们。可以将其类比为关系型数据库中的“表结构(Schema)”。当您索引一个文档时,ES会根据映射来确定如何存储和索引每个字段。例如,一个字段是 text 类型用于全文搜索,另一个字段是 keyword 类型用于精确匹配或聚合。

8. 分片 (Shard)

分片是Elasticsearch实现数据水平扩展和高可用性的核心机制。一个索引可以被分成多个分片。每个分片都是一个独立的Lucene索引,可以托管在集群中的任何节点上。
* 主分片 (Primary Shard):每个文档都存储在一个主分片中。一旦创建索引,主分片的数量就不能更改(除非重建索引)。
* 副本分片 (Replica Shard):主分片的副本。副本分片的作用是提供数据的冗余备份,防止硬件故障导致数据丢失;同时,它们还可以处理搜索请求,提高搜索吞吐量。副本分片的数量可以在索引创建后动态调整。

9. 倒排索引 (Inverted Index)

这是Elasticsearch实现高速全文搜索的关键。传统数据库是对行进行索引,而倒排索引是对文档中的“词”进行索引。它存储了每个词出现在哪些文档中,以及在文档中的位置等信息。当用户搜索某个词时,ES能快速地找到包含该词的所有文档。

第二章:环境搭建:让Elasticsearch奔跑起来

要开始使用Elasticsearch,首先需要搭建其运行环境。我们将介绍两种常见的安装方式:直接安装和使用Docker。

1. 前提条件

Elasticsearch 是用 Java 开发的,所以您的系统需要安装 Java Development Kit (JDK)。推荐安装对应ES版本的OpenJDK LTS(长期支持)版本。
* ES 7.x 建议使用 Java 8 或 Java 11。
* ES 8.x 建议使用 Java 17。

您可以从OpenJDK官方网站或通过包管理器(如 aptyumbrew)安装。

2. 直接安装 Elasticsearch

我们将以安装 Elasticsearch 8.x 版本为例。

步骤一:下载 Elasticsearch

访问 Elastic 官网下载页面 (https://www.elastic.co/cn/downloads/elasticsearch),选择适合您操作系统的安装包(例如 tar.gz for Linux/macOS, zip for Windows)。

“`bash

例如在 Linux/macOS 下下载 8.x 版本

wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-8.x.x-linux-x86_64.tar.gz
tar -zxvf elasticsearch-8.x.x-linux-x86_64.tar.gz
cd elasticsearch-8.x.x
“`

步骤二:配置 Elasticsearch

进入解压后的目录,编辑 config/elasticsearch.yml 文件。对于首次安装和单节点测试,通常需要调整以下配置:

“`yaml

config/elasticsearch.yml

—————— 集群配置 ——————-

cluster.name: my-application # 集群名称,保持唯一
node.name: node-1 # 节点名称,集群中唯一

—————— 网络配置 ——————-

network.host: 0.0.0.0 # 允许外部访问,生产环境请指定具体IP
http.port: 9200 # HTTP端口,默认9200

—————— 数据和日志路径 ——————-

path.data: /path/to/elasticsearch-8.x.x/data # 数据存储路径
path.logs: /path/to/elasticsearch-8.x.x/logs # 日志存储路径

—————— 内存配置 ——————-

ES 默认会占用一半可用内存,但不能超过32GB。

生产环境建议单独配置 JVM 内存。

在 jvm.options 文件中修改 -Xms 和 -Xmx

—————— 安全配置 (Elasticsearch 8.x 默认启用) ——————-

8.x 版本默认开启了安全功能,包括 TLS 和用户认证。

初次启动时,ES 会生成一个 elastic 用户和密码,以及一个 Kibana 注册令牌。

这些信息会在首次启动的控制台输出,请务必记录下来。

“`

步骤三:启动 Elasticsearch

“`bash

在 Elasticsearch 根目录下

./bin/elasticsearch
“`

首次启动时,ES 会自动生成安全配置,并在控制台输出如下信息:
* elastic 用户的密码
* kibana_system 用户的注册令牌(用于 Kibana 连接ES)

请务必将这些信息复制并保存好!

步骤四:验证 Elasticsearch

打开另一个终端,尝试访问ES服务:

“`bash

对于默认开启 TLS 和用户认证的 8.x 版本

curl -u elastic: –cacert config/certs/http_ca.crt -X GET “https://localhost:9200”

如果是旧版本或禁用了安全功能 (不推荐在生产环境这样做)

curl -X GET “http://localhost:9200”

“`

如果看到类似以下内容的JSON响应,说明Elasticsearch已成功启动并运行:

json
{
"name" : "node-1",
"cluster_name" : "my-application",
"cluster_uuid" : "...",
"version" : {
"number" : "8.x.x",
"build_flavor" : "default",
...
},
"tagline" : "You Know, for Search"
}

3. 安装 Kibana

Kibana 是 Elastic Stack 的一个重要组成部分,它提供了一个强大的Web界面,用于搜索、查看和可视化Elasticsearch索引中的数据。

步骤一:下载 Kibana

访问 Kibana 官网下载页面 (https://www.elastic.co/cn/downloads/kibana),选择与您ES版本匹配的Kibana版本。

“`bash

例如在 Linux/macOS 下下载 8.x 版本

wget https://artifacts.elastic.co/downloads/kibana/kibana-8.x.x-linux-x86_64.tar.gz
tar -zxvf kibana-8.x.x-linux-x86_64.tar.gz
cd kibana-8.x.x
“`

步骤二:配置 Kibana

进入解压后的目录,编辑 config/kibana.yml 文件。

“`yaml

config/kibana.yml

—————— Kibana 服务器配置 ——————-

server.port: 5601
server.host: “0.0.0.0” # 允许外部访问

—————— Elasticsearch 连接配置 ——————-

elasticsearch.hosts: [“https://localhost:9200”] # ES集群地址

elasticsearch.username: “kibana_system” # Kibana 连接 ES 的用户,默认是kibana_system

对于 ES 8.x 默认开启安全的情况,Kibana 连接需要使用注册令牌

当您首次启动 ES 时,会生成一个注册令牌,类似如下:

bin/kibana –allow-root –enrollment-token

“`

步骤三:启动 Kibana

“`bash

在 Kibana 根目录下

./bin/kibana
“`

首次启动 Kibana 时,它会提示您输入在ES首次启动时生成的 kibana_system 用户的注册令牌(enrollment token)。将其粘贴到终端,Kibana 将会自动配置并连接到Elasticsearch。

步骤四:验证 Kibana

在浏览器中访问 http://localhost:5601。如果一切顺利,您将看到 Kibana 的登录界面。使用 elastic 用户和您之前保存的密码登录。成功登录后,您就可以开始使用Kibana的各种功能了。

4. 使用 Docker 安装 (推荐用于快速启动)

对于初学者和开发环境,使用 Docker 是最快速、最便捷的方式。

步骤一:安装 Docker

确保您的系统已安装 Docker 和 Docker Compose。

步骤二:创建 docker-compose.yml 文件

创建一个名为 docker-compose.yml 的文件,内容如下(注意:对于8.x版本,需要处理安全配置,这里提供一个简化的7.x或禁用安全性的8.x配置,更复杂的8.x安全配置请参考官方文档):

“`yaml
version: ‘3.8’

services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:8.x.x # 替换为实际版本
container_name: elasticsearch
environment:
– discovery.type=single-node # 单节点模式
# 对于 8.x 版本,需要处理安全配置,例如禁用安全 (不推荐用于生产)
– xpack.security.enabled=false
– xpack.security.http.ssl.enabled=false
– xpack.security.transport.ssl.enabled=false
# 对于 7.x 版本,默认无需额外安全配置
– ES_JAVA_OPTS=-Xms512m -Xmx512m # 限制内存使用
volumes:
– esdata:/usr/share/elasticsearch/data # 数据持久化
ports:
– “9200:9200”
– “9300:9300” # 节点间通信端口
networks:
– elastic-net

kibana:
image: docker.elastic.co/kibana/kibana:8.x.x # 替换为实际版本
container_name: kibana
environment:
– ELASTICSEARCH_HOSTS=http://elasticsearch:9200 # 连接 ES 服务,注意服务名称
# 对于 ES 8.x 禁用安全的情况
– ELASTICSEARCH_USERNAME=elastic
– ELASTICSEARCH_PASSWORD=changeme # 如果ES有密码,这里也要配置
ports:
– “5601:5601”
depends_on:
– elasticsearch
networks:
– elastic-net

volumes:
esdata: # 定义数据卷

networks:
elastic-net: # 定义网络
“`

重要提示:上述 docker-compose.yml 是为了演示方便,直接禁用了 Elasticsearch 8.x 的安全功能。在生产环境中,强烈不建议禁用安全性。如果需要启用安全性,docker-compose.yml 会复杂得多,涉及到证书生成和管理,请参考Elastic官方的Docker部署指南。

步骤三:启动服务

docker-compose.yml 文件所在的目录下执行:

bash
docker-compose up -d

这将启动 Elasticsearch 和 Kibana 容器。稍等片刻,您就可以通过 http://localhost:9200 访问 Elasticsearch,通过 http://localhost:5601 访问 Kibana。

第三章:初探究竟:Kibana Dev Tools与基本操作 (CRUD)

Kibana 提供了一个名为 Dev Tools (开发工具) 的强大功能,它允许您直接通过REST API向Elasticsearch发送请求。这是学习ES操作最直观、最便捷的方式。

在 Kibana 中,点击左侧导航栏的 Dev Tools 图标,您会看到一个类似于命令行工具的界面:左侧是请求区域,右侧是响应区域。

1. 创建索引 (Create Index)

在 Elasticseach 中,索引是存储文档的逻辑命名空间。

json
PUT /my_first_index
{
"settings": {
"number_of_shards": 1, // 主分片数量,一旦创建不可更改
"number_of_replicas": 0 // 副本分片数量,可动态调整
},
"mappings": {
"properties": {
"title": { "type": "text" },
"author": { "type": "keyword" },
"publish_date": { "type": "date" },
"views": { "type": "integer" }
}
}
}

  • PUT /my_first_index:使用 PUT 请求创建一个名为 my_first_index 的索引。
  • settings:定义索引的设置,例如分片和副本数量。
  • mappings:定义索引中文档的字段映射(Schema)。这里我们定义了四个字段:
    • titletext 类型,适用于全文搜索。
    • authorkeyword 类型,适用于精确匹配和聚合。
    • publish_datedate 类型,用于日期相关的查询。
    • viewsinteger 类型,用于数值比较。

2. 索引文档 (Index Document – Create/Update)

向索引中添加文档,或更新现有文档。

方式一:自动生成文档ID

ES 会为文档自动生成一个唯一的ID。

json
POST /my_first_index/_doc
{
"title": "Elasticsearch 入门教程",
"author": "张三",
"publish_date": "2023-01-15",
"views": 1200
}

响应:

json
{
"_index": "my_first_index",
"_id": "AXjZzXAB-y0x_yYw", // ES 自动生成的 ID
"_version": 1,
"result": "created",
"_shards": {
"total": 1,
"successful": 1,
"failed": 0
},
"_seq_no": 0,
"_primary_term": 1
}

方式二:手动指定文档ID

您可以为文档指定一个唯一的ID。如果ID已存在,则会更新该文档。

json
PUT /my_first_index/_doc/1
{
"title": "深入理解 Elasticsearch",
"author": "李四",
"publish_date": "2023-03-20",
"views": 2500
}

响应:

json
{
"_index": "my_first_index",
"_id": "1", // 我们指定的 ID
"_version": 1,
"result": "created",
"_shards": { ... }
}

再次 PUT 同一个ID的文档,ES会将其视为更新操作,并增加 _version

json
PUT /my_first_index/_doc/1
{
"title": "深入理解 Elasticsearch:核心原理",
"author": "李四",
"publish_date": "2023-03-20",
"views": 2800,
"tags": ["database", "search"]
}

响应中的 result 将变为 "updated"_version 变为 2

3. 获取文档 (Get Document – Read)

通过文档ID获取单个文档。

json
GET /my_first_index/_doc/1

响应:

json
{
"_index": "my_first_index",
"_id": "1",
"_version": 2,
"_seq_no": 1,
"_primary_term": 1,
"found": true,
"_source": { // 原始文档内容
"title": "深入理解 Elasticsearch:核心原理",
"author": "李四",
"publish_date": "2023-03-20",
"views": 2800,
"tags": ["database", "search"]
}
}

4. 更新文档 (Update Document)

除了通过 PUT /_doc/<id> 全量替换文档外,ES还支持局部更新,这更加高效。

json
POST /my_first_index/_update/1
{
"doc": {
"views": 3000,
"status": "published"
}
}

响应:

json
{
"_index": "my_first_index",
"_id": "1",
"_version": 3,
"result": "updated",
"_shards": { ... }
}

此时,文档ID为 1views 字段变为 3000,并新增了一个 status 字段。其他字段如 titleauthor 等保持不变。

5. 删除文档 (Delete Document)

通过文档ID删除单个文档。

json
DELETE /my_first_index/_doc/1

响应:

json
{
"_index": "my_first_index",
"_id": "1",
"_version": 4,
"result": "deleted",
"_shards": { ... }
}

6. 删除索引 (Delete Index)

删除整个索引及其所有文档。请谨慎操作!

json
DELETE /my_first_index

响应:

json
{
"acknowledged": true // 表示请求已被接受
}

第四章:搜索的艺术:Elasticsearch核心魅力

搜索是Elasticsearch的核心功能。它提供了强大且灵活的查询语言——Query DSL (Domain Specific Language)

为了演示搜索功能,我们先重新创建 my_first_index 并插入一些示例文档:

“`json
PUT /my_first_index
{
“settings”: { “number_of_shards”: 1, “number_of_replicas”: 0 },
“mappings”: {
“properties”: {
“title”: { “type”: “text” },
“author”: { “type”: “keyword” },
“content”: { “type”: “text” },
“publish_date”: { “type”: “date” },
“views”: { “type”: “integer” },
“tags”: { “type”: “keyword” },
“price”: { “type”: “float” }
}
}
}

POST /my_first_index/_doc
{
“title”: “Elasticsearch 入门指南”,
“author”: “张三”,
“content”: “这是一篇关于 Elasticsearch 入门基础知识的指南。”,
“publish_date”: “2023-01-01”,
“views”: 1500,
“tags”: [“search”, “bigdata”],
“price”: 29.99
}

POST /my_first_index/_doc
{
“title”: “Kibana 数据可视化实战”,
“author”: “李四”,
“content”: “学习如何使用 Kibana 进行数据探索和可视化。”,
“publish_date”: “2023-02-10”,
“views”: 2200,
“tags”: [“kibana”, “visualization”],
“price”: 39.50
}

POST /my_first_index/_doc
{
“title”: “深入理解 Lucene 核心”,
“author”: “王五”,
“content”: “探索 Lucene 倒排索引和查询原理。”,
“publish_date”: “2023-03-05”,
“views”: 1800,
“tags”: [“lucene”, “search_engine”],
“price”: 49.00
}

POST /my_first_index/_doc
{
“title”: “大数据技术栈:Elasticsearch 与 Kafka”,
“author”: “张三”,
“content”: “介绍 Elasticsearch 如何与 Kafka 协同工作。”,
“publish_date”: “2023-04-20”,
“views”: 3000,
“tags”: [“bigdata”, “kafka”],
“price”: 55.20
}

POST /my_first_index/_doc
{
“title”: “云计算与分布式系统”,
“author”: “李四”,
“content”: “分布式系统在云计算环境中的应用。”,
“publish_date”: “2023-05-15”,
“views”: 1000,
“tags”: [“cloud”, “distributed”],
“price”: 60.00
}
“`

1. 基本搜索

A. 匹配所有文档

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

  • _search:搜索API的端点。
  • query:搜索请求的主体。
  • match_all:匹配索引中的所有文档。

B. 查询字符串搜索 (Query String Query)

这是一种简单的查询方式,类似于在浏览器中输入搜索关键词。

json
GET /my_first_index/_search?q=Elasticsearch

这将搜索 my_first_index 中所有字段包含 “Elasticsearch” 的文档。

2. Query DSL:结构化查询

Query DSL 是通过JSON请求体构建查询的方式,它提供了极大的灵活性和表现力。

A. match 查询 (全文匹配)

用于对 text 类型的字段进行全文搜索,会进行分词处理。

json
GET /my_first_index/_search
{
"query": {
"match": {
"content": "Elasticsearch 入门"
}
}
}

这将搜索 content 字段包含 “Elasticsearch” 或 “入门” 的文档。ES会对查询字符串和文档内容都进行分词,然后匹配分词后的结果。

B. term 查询 (精确匹配)

用于对 keywordnumericdate 等类型的字段进行精确匹配,不会进行分词。

json
GET /my_first_index/_search
{
"query": {
"term": {
"author.keyword": "张三" // 注意:对 text 字段精确匹配需使用 .keyword 后缀
}
}
}

这将精确匹配 author 字段为 “张三” 的文档。

C. range 查询 (范围匹配)

用于数值或日期字段的范围查询。

json
GET /my_first_index/_search
{
"query": {
"range": {
"views": {
"gte": 2000, // 大于等于 (Greater Than or Equal)
"lte": 3000 // 小于等于 (Less Than or Equal)
}
}
}
}

这将查找 views 字段在 2000 到 3000 之间的文档。
其他操作符:gt (大于), lt (小于)。

D. bool 查询 (组合查询)

bool 查询是 Query DSL 中最常用的复合查询,它允许您组合多个查询条件,并指定它们之间的逻辑关系:
* must:文档必须匹配所有 must 子句(等同于 AND)。
* should:文档应该匹配至少一个 should 子句(等同于 OR)。
* must_not:文档不能匹配任何 must_not 子句(等同于 NOT)。
* filter:文档必须匹配所有 filter 子句。与 must 不同,filter 子句在执行时不会计算相关性得分 (_score),因此通常比 must 更快,适用于不需要排序的过滤场景。

示例:查找作者为“张三”且标题包含“Elasticsearch”或“Kibana”,但浏览量低于2000的文档。

json
GET /my_first_index/_search
{
"query": {
"bool": {
"must": [
{ "term": { "author.keyword": "张三" } }
],
"should": [
{ "match": { "title": "Elasticsearch" } },
{ "match": { "title": "Kibana" } }
],
"must_not": [
{ "range": { "views": { "gte": 2000 } } }
],
"minimum_should_match": 1, // 至少匹配一个 should 子句
"filter": [
{ "range": { "publish_date": { "gte": "2023-01-01" } } }
]
}
}
}

3. 结果排序、分页与高亮

A. 排序 (Sort)

json
GET /my_first_index/_search
{
"query": { "match_all": {} },
"sort": [
{ "views": { "order": "desc" } }, // 按浏览量降序
{ "publish_date": { "order": "asc" } } // 浏览量相同则按发布日期升序
]
}

B. 分页 (Pagination)

使用 fromsize 参数。from 是起始文档的偏移量,size 是返回的文档数量。

json
GET /my_first_index/_search
{
"query": { "match_all": {} },
"from": 0, // 从第0个文档开始
"size": 2 // 返回2个文档
}

C. 高亮 (Highlighting)

在搜索结果中,将匹配到的关键词进行高亮显示,增强用户体验。

json
GET /my_first_index/_search
{
"query": {
"match": {
"content": "Elasticsearch"
}
},
"highlight": {
"fields": {
"content": {} // 对 content 字段进行高亮
},
"pre_tags": ["<em>"], // 前缀标签
"post_tags": ["</em>"] // 后缀标签
}
}

在返回结果的 hits.hits._source 同级,会有一个 highlight 字段包含高亮后的文本。

4. 聚合 (Aggregations)

聚合是Elasticsearch的另一个强大功能,它允许您对数据进行分组、统计和分析,类似于SQL中的 GROUP BY

A. terms 聚合 (分组统计)

按某个字段的值进行分组,并统计每个组的文档数量。

json
GET /my_first_index/_search
{
"size": 0, // 不返回实际文档,只返回聚合结果
"aggs": {
"articles_by_author": {
"terms": {
"field": "author.keyword", // 对 author 字段进行聚合
"size": 10 // 返回前10个作者
}
}
}
}

结果将在 aggregations 字段中返回,显示每个作者发表的文章数量。

B. 统计聚合 (Metric Aggregations)

计算字段的平均值、最大值、最小值、总和等。

json
GET /my_first_index/_search
{
"size": 0,
"aggs": {
"avg_views": {
"avg": {
"field": "views" // 计算 views 字段的平均值
}
},
"max_price": {
"max": {
"field": "price" // 计算 price 字段的最大值
}
}
}
}

C. 组合聚合 (Nested Aggregations)

可以将多个聚合组合在一起,实现更复杂的分析。例如,按作者分组,然后统计每个作者文章的平均浏览量。

json
GET /my_first_index/_search
{
"size": 0,
"aggs": {
"articles_by_author": {
"terms": {
"field": "author.keyword",
"size": 10
},
"aggs": { // 嵌套聚合
"avg_views_per_author": {
"avg": {
"field": "views"
}
}
}
}
}
}

第五章:掌控数据结构:Mapping详解

映射 (Mapping) 是 Elasticsearch 中定义索引结构和数据类型的方式。它是数据正确存储、高效搜索和精准分析的基础。

1. 动态映射 (Dynamic Mapping)

当您第一次向一个索引(或现有索引中的新字段)添加文档,而没有预先定义映射时,Elasticsearch 会尝试根据字段的值自动推断其数据类型,并创建动态映射。

示例:
如果您直接索引一个文档,而 my_first_index 还没有 new_field 的映射:

json
POST /my_first_index/_doc
{
"title": "动态映射示例",
"new_field": "这是一个新字段", // 字符串会被映射为 text 和 keyword
"another_number": 123 // 数字会被映射为 long
}

ES 会自动为 new_field 创建 textkeyword 类型的映射,为 another_number 创建 long 类型的映射。

查看索引映射:

json
GET /my_first_index/_mapping

2. 显式映射 (Explicit Mapping)

虽然动态映射很方便,但在生产环境中,强烈推荐使用显式映射。它为您提供了对字段类型、分析器、多字段等高级特性的精确控制,确保数据按预期存储和搜索。

显式映射的优势:
* 精确的数据类型:避免ES误判,例如将数字字符串映射为 text
* 控制字段行为:例如,是否进行分词,是否存储原始值。
* 优化存储和性能:选择最合适的数据类型可以节省磁盘空间,提高查询效率。
* 多字段 (Multi-fields):一个字段可以有多种索引方式(例如 title 既可以作为 text 用于全文搜索,也可以作为 keyword 用于精确过滤和聚合)。
* 自定义分析器 (Analyzers):根据业务需求定制分词逻辑。

示例:创建一个带有显式映射的新索引 products_index

json
PUT /products_index
{
"settings": {
"number_of_shards": 1,
"number_of_replicas": 0
},
"mappings": {
"properties": {
"product_id": {
"type": "keyword" // 商品ID,精确匹配,不分词
},
"name": {
"type": "text", // 商品名称,用于全文搜索
"analyzer": "ik_smart", // 指定中文分词器 (假设已安装 ik-analyzer 插件)
"fields": {
"keyword": {
"type": "keyword", // 同一字段,也作为一个 keyword 类型存储,用于精确匹配/排序
"ignore_above": 256 // 超过256字符不索引为 keyword
}
}
},
"description": {
"type": "text", // 商品描述
"analyzer": "ik_max_word"
},
"price": {
"type": "float" // 价格,浮点数
},
"stock": {
"type": "integer" // 库存,整数
},
"category": {
"type": "keyword" // 商品分类,精确匹配
},
"on_sale": {
"type": "boolean" // 是否在售
},
"created_at": {
"type": "date", // 创建时间
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis" // 支持多种日期格式
},
"location": {
"type": "geo_point" // 地理位置信息,用于地理空间搜索
}
}
}
}

关键数据类型说明:

  • text: 用于全文文本,会被分词器分析成独立的词项,然后建立倒排索引。适用于搜索大段文本,如商品描述、文章内容。
  • keyword: 用于精确值,不会被分词,直接作为完整的词项进行索引。适用于商品ID、标签、分类、人名等需要精确匹配、排序或聚合的字段。
  • long, integer, short, byte: 整数类型,根据数值范围选择。
  • double, float: 浮点数类型,根据精度需求选择。
  • boolean: 布尔值(truefalse)。
  • date: 日期和时间类型。ES支持多种日期格式,也可以自定义格式。
  • object: 用于存储JSON对象。当一个字段的值本身是另一个JSON对象时,ES会将其映射为 object 类型。
  • nested: 专门用于处理JSON数组中的对象,当数组中的每个对象都应被独立索引和查询时使用。
  • geo_point: 地理位置类型,用于存储经纬度坐标,支持地理空间查询(如“查找附近X公里内的商店”)。

3. 字段分析器 (Analyzers)

对于 text 类型的字段,ES会使用分析器 (Analyzer) 进行文本处理。一个分析器由字符过滤器 (Character Filters)、分词器 (Tokenizer) 和词元过滤器 (Token Filters) 组成。

  • 默认分析器 (Standard Analyzer):ES的默认分析器,对文本进行基本的标点符号处理和转换为小写。
  • 中文分词器:对于中文文本,标准分析器效果不佳。通常需要安装第三方插件,如 IK Analyzer
    • IK Smart: 细粒度分词,适合搜索。
    • IK Max Word: 最细粒度分词,包含更多可能的词语。

安装 IK Analyzer 插件:

“`bash

在 Elasticsearch 根目录执行

./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v8.x.x/elasticsearch-analysis-ik-8.x.x.zip
``
(请将
8.x.x` 替换为您的ES版本,并确保下载对应版本的插件)。安装后需要重启Elasticsearch。

第六章:与Elasticsearch交互:更多工具

除了 Kibana Dev Tools,还有多种方式可以与Elasticsearch进行交互。

1. REST API (使用 curl 命令)

所有Elasticsearch操作都通过RESTful API暴露,您可以使用任何HTTP客户端与其交互。curl 是一个命令行工具,非常适合进行测试和脚本化操作。我们已经在之前的例子中使用了 curl 来验证ES启动。

“`bash

获取集群健康状态 (需要认证和CA证书)

curl -u elastic: –cacert config/certs/http_ca.crt -X GET “https://localhost:9200/_cat/health?v”

索引文档

curl -u elastic: –cacert config/certs/http_ca.crt -X POST “https://localhost:9200/my_first_index/_doc” -H “Content-Type: application/json” -d’
{
“title”: “使用curl索引文档”,
“author”: “未知”,
“views”: 1
}

“`

2. 官方客户端库 (Client Libraries)

Elasticsearch 提供了多种语言的官方客户端库,方便开发者在应用程序中集成ES功能。这些库封装了RESTful API,提供了更友好的编程接口。

  • Java: org.elasticsearch.client:elasticsearch-rest-high-level-client (对于8.x,推荐使用新的 elasticsearch-java 客户端)
  • Python: elasticsearch-py
  • Go: go-elasticsearch
  • JavaScript: @elastic/elasticsearch
  • .NET: NEST
  • Ruby: elasticsearch-ruby
  • PHP: elasticsearch-php

Python 客户端示例:

“`python
from elasticsearch import Elasticsearch

连接到 Elasticsearch (8.x 版本需要指定云ID和API Key,或用户名/密码/证书)

es = Elasticsearch(
hosts=[“https://localhost:9200”],
basic_auth=(“elastic”, ““),
ca_certs=”path/to/elasticsearch-8.x.x/config/certs/http_ca.crt”
)

检查连接

print(es.info())

索引文档

doc = {
“title”: “使用Python客户端索引文档”,
“author”: “Python Developer”,
“publish_date”: “2023-08-15”,
“views”: 50
}
resp = es.index(index=”my_first_index”, document=doc)
print(resp[‘result’])

搜索文档

query = {
“match”: {
“title”: “Python”
}
}
resp = es.search(index=”my_first_index”, query=query)
for hit in resp[‘hits’][‘hits’]:
print(f”ID: {hit[‘_id’]}, Source: {hit[‘_source’]}”)
“`

3. Logstash 与 Beats (数据采集)

  • Logstash: 一个开源的数据收集引擎,可以动态地从各种来源(如日志文件、数据库、Kafka、MQTT等)获取数据,进行转换,然后发送到Elasticsearch。
  • Beats: 一组轻量级数据传输工具,用于将不同类型的数据从边缘设备或服务器传输到Elasticsearch或Logstash。例如:
    • Filebeat: 收集日志文件。
    • Metricbeat: 收集系统和服务的指标数据。
    • Winlogbeat: 收集 Windows 事件日志。
    • Heartbeat: 监控服务可用性(Uptime)。

它们构成了经典的 ELK Stack (Elasticsearch, Logstash, Kibana),现在通常称为 Elastic Stack

第七章:实际应用场景

Elasticsearch 在众多领域都有广泛应用:

  1. 站内搜索 / 电商搜索: 淘宝、京东等电商平台使用ES提供快速、精准的商品搜索、筛选和推荐功能。
  2. 日志分析与监控: 结合 Logstash 和 Kibana,构建实时的日志收集、存储、搜索和可视化平台,用于系统故障排查、性能监控和安全审计。
  3. 数据可视化与商业智能: 将各种业务数据导入ES,利用Kibana构建交互式仪表盘,进行数据探索和商业决策。
  4. 安全信息和事件管理 (SIEM): 收集安全日志和事件,利用ES的强大搜索和聚合能力,实时检测和分析潜在的安全威胁。
  5. 全文检索系统: 为文档管理系统、新闻网站、知识库提供强大的全文检索能力。
  6. 地理空间数据分析: 存储和查询地理位置信息,应用于LBS(Location Based Service)服务、物流路径优化等。

第八章:进阶之路与最佳实践

掌握了基础知识后,Elasticsearch的学习之旅才刚刚开始。以下是一些进阶方向和最佳实践:

1. 集群规划与部署

  • 节点角色分配: 根据业务需求合理分配主节点、数据节点、协调节点等,避免单点故障和资源瓶颈。
  • 硬件配置: CPU、内存、磁盘(SSD是数据节点的首选)和网络带宽对ES性能至关重要。
  • JVM 内存调优: 合理设置 -Xms-Xmx,通常设置为物理内存的50%,但不超过32GB。

2. 性能优化

  • 合理的映射设计: 使用最合适的数据类型,善用 keywordtext 的区分,利用 multi-fields
  • 查询优化: 优先使用 filter 上下文进行过滤,而不是 must,因为 filter 不计算分数,性能更高。避免 script 查询的滥用。
  • 批量操作: 索引、更新和删除文档时,使用 _bulk API 进行批量操作,可以显著提高吞吐量。
  • 分片和副本数量: 根据数据量和集群规模合理配置,过多或过少都会影响性能。
  • 缓存: ES内部有多种缓存机制,理解并利用它们。

3. 索引生命周期管理 (ILM)

随着数据量的增长,需要管理数据的生命周期。ILM 允许您定义策略,自动在数据变老时将其从热(hot)阶段移动到暖(warm)、冷(cold)和冻结(frozen)阶段,并最终删除。这有助于优化存储成本和查询性能。

4. 安全性

  • 启用 X-Pack Security: 在生产环境中,务必开启Elasticsearch的认证、授权、TLS加密和审计功能。
  • 角色与权限管理: 根据用户职责分配最小必要权限。

5. 高可用性与灾备

  • 副本分片: 至少一个副本分片以提供数据冗余和故障恢复能力。
  • 快照与恢复 (Snapshot and Restore): 定期对索引数据进行快照备份,以便在发生灾难性故障时进行恢复。
  • 跨集群复制 (CCR): 用于在不同的数据中心或集群之间进行数据同步,实现异地容灾。

6. 数据模型设计

良好的数据模型是高效搜索的基础。思考如何将业务数据扁平化、非规范化,以适应ES的倒排索引结构,避免多表 Join 查询带来的复杂性。

结语:探索数据的无限可能

恭喜您,已经完成了Elasticsearch的入门之旅!从核心概念到环境搭建,从基本CRUD到强大的搜索和聚合,您已经掌握了Elasticsearch的基本操作和原理。

Elasticsearch 不仅仅是一个搜索引擎,它更是一个强大的数据分析平台,是构建现代数据驱动应用不可或缺的组件。随着您对它的深入学习和实践,您会发现它在处理海量数据、提供实时洞察方面的巨大潜力。

数据世界浩瀚无垠,Elasticsearch 正是您探索这片领域的利器。持续学习,不断实践,相信您一定能充分驾驭它,为您的项目带来无限可能!


发表评论

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

滚动至顶部