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)”。例如,一个商品文档可能有 name、price、description 等字段。
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官方网站或通过包管理器(如 apt、yum、brew)安装。
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:
如果是旧版本或禁用了安全功能 (不推荐在生产环境这样做)
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)。这里我们定义了四个字段:title:text类型,适用于全文搜索。author:keyword类型,适用于精确匹配和聚合。publish_date:date类型,用于日期相关的查询。views:integer类型,用于数值比较。
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为 1 的 views 字段变为 3000,并新增了一个 status 字段。其他字段如 title、author 等保持不变。
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 查询 (精确匹配)
用于对 keyword、numeric、date 等类型的字段进行精确匹配,不会进行分词。
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)
使用 from 和 size 参数。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 创建 text 和 keyword 类型的映射,为 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: 布尔值(true或false)。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:
索引文档
curl -u elastic:
{
“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 在众多领域都有广泛应用:
- 站内搜索 / 电商搜索: 淘宝、京东等电商平台使用ES提供快速、精准的商品搜索、筛选和推荐功能。
- 日志分析与监控: 结合 Logstash 和 Kibana,构建实时的日志收集、存储、搜索和可视化平台,用于系统故障排查、性能监控和安全审计。
- 数据可视化与商业智能: 将各种业务数据导入ES,利用Kibana构建交互式仪表盘,进行数据探索和商业决策。
- 安全信息和事件管理 (SIEM): 收集安全日志和事件,利用ES的强大搜索和聚合能力,实时检测和分析潜在的安全威胁。
- 全文检索系统: 为文档管理系统、新闻网站、知识库提供强大的全文检索能力。
- 地理空间数据分析: 存储和查询地理位置信息,应用于LBS(Location Based Service)服务、物流路径优化等。
第八章:进阶之路与最佳实践
掌握了基础知识后,Elasticsearch的学习之旅才刚刚开始。以下是一些进阶方向和最佳实践:
1. 集群规划与部署
- 节点角色分配: 根据业务需求合理分配主节点、数据节点、协调节点等,避免单点故障和资源瓶颈。
- 硬件配置: CPU、内存、磁盘(SSD是数据节点的首选)和网络带宽对ES性能至关重要。
- JVM 内存调优: 合理设置
-Xms和-Xmx,通常设置为物理内存的50%,但不超过32GB。
2. 性能优化
- 合理的映射设计: 使用最合适的数据类型,善用
keyword和text的区分,利用multi-fields。 - 查询优化: 优先使用
filter上下文进行过滤,而不是must,因为filter不计算分数,性能更高。避免script查询的滥用。 - 批量操作: 索引、更新和删除文档时,使用
_bulkAPI 进行批量操作,可以显著提高吞吐量。 - 分片和副本数量: 根据数据量和集群规模合理配置,过多或过少都会影响性能。
- 缓存: 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 正是您探索这片领域的利器。持续学习,不断实践,相信您一定能充分驾驭它,为您的项目带来无限可能!