Elasticsearch 零基础教程:快速上手与应用开发 – wiki基地

Elasticsearch 零基础教程:快速上手与应用开发

导语

在当今数据爆炸的时代,如何高效地存储、检索和分析海量数据成为了企业和开发者面临的共同挑战。Elasticsearch 正是为了解决这一痛点而诞生的。它是一个基于 Lucene 的开源、分布式、RESTful 风格的搜索和数据分析引擎,以其强大的全文搜索能力、实时数据分析和高可扩展性而闻名。

无论你是数据工程师、后端开发者还是对数据处理感兴趣的技术爱好者,掌握 Elasticsearch 都将为你打开数据世界的新大门。本教程旨在帮助零基础的读者快速上手 Elasticsearch,并了解如何将其应用于实际的项目开发中。

一、什么是 Elasticsearch?

Elasticsearch (通常简称 ES) 是 Elastic Stack(以前称为 ELK Stack,现在是 Elastic Stack)的核心组件之一,由 Elasticsearch、Kibana、Logstash 和 Beats 组成。

  • 搜索与分析引擎:Elasticsearch 最核心的功能是提供强大的全文搜索能力和实时数据分析。它可以快速索引大量数据,并在毫秒级内返回复杂的查询结果。
  • 分布式:ES 天生就是分布式的,可以轻松地扩展到数百台服务器,处理 PB 级别的数据。
  • RESTful API:通过标准的 RESTful API 进行交互,使得开发者可以使用任何编程语言轻松地与 ES 进行通信。
  • JSON 文档存储:ES 以 JSON 文档的形式存储数据,非常灵活且易于理解。
  • Schema-less (部分):虽然 ES 最终会有自己的 Schema(映射),但在插入文档时通常不需要预先定义 Schema,ES 会根据数据类型自动推断。

为什么选择 Elasticsearch?

  • 速度:无论是索引还是搜索,ES 都以其卓越的速度著称。
  • 扩展性:轻松应对数据增长,通过增加节点即可线性扩展。
  • 功能强大:支持复杂的查询、过滤、聚合、地理位置搜索等。
  • 生态系统:拥有成熟的生态系统和丰富的客户端库,易于集成。

二、快速上手 Elasticsearch

2.1 安装 Elasticsearch

对于初学者来说,使用 Docker 是最快速、最简便的安装和运行 Elasticsearch 的方式。

前提条件:确保你的机器上已经安装了 Docker 和 Docker Compose。

步骤

  1. 创建 docker-compose.yml 文件

    “`yaml
    version: ‘3.8’
    services:
    elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.17.0 # 可以选择其他版本
    container_name: elasticsearch
    environment:
    – discovery.type=single-node # 单节点模式
    – “ES_JAVA_OPTS=-Xms512m -Xmx512m” # 设置JVM内存
    ulimits:
    memlock:
    soft: -1
    hard: -1
    volumes:
    – esdata:/usr/share/elasticsearch/data # 数据持久化
    ports:
    – 9200:9200 # HTTP API 端口
    – 9300:9300 # 节点间通信端口
    networks:
    – es_network

    kibana:
    image: docker.elastic.co/kibana/kibana:7.17.0 # 版本需与ES保持一致
    container_name: kibana
    environment:
    – ELASTICSEARCH_HOSTS=http://elasticsearch:9200 # 连接ES
    ports:
    – 5601:5601 # Kibana UI 端口
    networks:
    – es_network
    depends_on:
    – elasticsearch

    volumes:
    esdata:
    driver: local

    networks:
    es_network:
    driver: bridge
    “`

    注意discovery.type=single-node 仅用于开发环境的单节点设置。生产环境需要多节点集群配置。

  2. 启动服务
    docker-compose.yml 文件所在的目录下,运行:

    bash
    docker-compose up -d

  3. 验证安装
    稍等片刻,待容器启动后,在浏览器中访问 http://localhost:9200。如果看到类似以下的 JSON 响应,说明 Elasticsearch 已经成功运行:

    json
    {
    "name" : "elasticsearch",
    "cluster_name" : "docker-cluster",
    "cluster_uuid" : "...",
    "version" : {
    "number" : "7.17.0",
    "build_flavor" : "default",
    "build_type" : "docker",
    "build_hash" : "...",
    "build_date" : "2022-02-08T22:36:09.1678265",
    "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"
    }

    同时,访问 http://localhost:5601 可以打开 Kibana,它是 Elasticsearch 的一个可视化工具,方便你管理和查询数据。

2.2 Elasticsearch 的核心概念

在进行操作之前,了解几个核心概念至关重要:

  • Index (索引):类比于关系型数据库中的“数据库(Database)”。它是具有相似特征的文档的集合。例如,你可以有一个 products 索引来存储所有商品信息,一个 logs 索引来存储日志数据。
  • Document (文档):ES 中可被索引的最小单位,类比于关系型数据库中的“行(Row)”。每个文档都是一个 JSON 对象,包含了一组键值对。
  • Field (字段):文档中的键值对,类比于关系型数据库中的“列(Column)”。
  • Type (类型):在 Elasticsearch 7.x 及更高版本中,一个索引只能有一个类型 (_doc)。在早期版本中,一个索引可以有多个类型,但这一概念已被废弃。
  • Node (节点):一个运行的 Elasticsearch 实例。
  • Cluster (集群):由一个或多个节点组成的集合,它们共同存储数据并提供索引和搜索能力。
  • Shard (分片):索引被水平分割成多个分片。每个分片都是一个独立的 Lucene 索引。这使得 ES 能够分布式地存储和处理数据。
  • Replica (副本):分片的副本。副本提供了数据冗余,防止硬件故障导致数据丢失,同时也可以提高搜索吞吐量。

2.3 基本操作

Elasticsearch 提供 RESTful API 进行交互。你可以使用 curl 命令、Postman 或任何 HTTP 客户端。

示例数据:我们将使用一些简单的“图书”数据。

2.3.1 索引文档 (Index Document)

将一个 JSON 文档添加到指定的索引中。

“`bash

自动生成文档ID

curl -X POST “localhost:9200/books/_doc?pretty” -H ‘Content-Type: application/json’ -d’
{
“title”: “深入理解Elasticsearch”,
“author”: “张三”,
“publish_year”: 2020,
“tags”: [“Elasticsearch”, “搜索”, “数据分析”],
“price”: 99.00
}

指定文档ID

curl -X PUT “localhost:9200/books/_doc/1?pretty” -H ‘Content-Type: application/json’ -d’
{
“title”: “Elasticsearch实战”,
“author”: “李四”,
“publish_year”: 2021,
“tags”: [“Elasticsearch”, “实战”],
“price”: 120.50
}

“`

2.3.2 获取文档 (Get Document)

根据文档 ID 获取单个文档。

bash
curl -X GET "localhost:9200/books/_doc/1?pretty"

2.3.3 搜索文档 (Search Document)

这是 Elasticsearch 最核心的功能。

a. 全文搜索 (匹配所有字段)

bash
curl -X GET "localhost:9200/books/_search?q=搜索&pretty"

b. 精准搜索 (使用 Query DSL – Domain Specific Language)

bash
curl -X GET "localhost:9200/books/_search?pretty" -H 'Content-Type: application/json' -d'
{
"query": {
"match": {
"title": "Elasticsearch"
}
}
}
'

c. 组合查询 (搜索书名包含 “Elasticsearch” 且作者为 “张三” 的书)

bash
curl -X GET "localhost:9200/books/_search?pretty" -H 'Content-Type: application/json' -d'
{
"query": {
"bool": {
"must": [
{ "match": { "title": "Elasticsearch" }},
{ "match": { "author": "张三" }}
]
}
}
}
'

2.3.4 更新文档 (Update Document)

  • 局部更新:只更新文档的部分字段。

    bash
    curl -X POST "localhost:9200/books/_update/1?pretty" -H 'Content-Type: application/json' -d'
    {
    "doc": {
    "price": 110.00
    }
    }
    '

  • 替换更新 (完全替换文档,与 PUT 相同):

    bash
    curl -X PUT "localhost:9200/books/_doc/1?pretty" -H 'Content-Type: application/json' -d'
    {
    "title": "Elasticsearch实战 - 第二版",
    "author": "李四",
    "publish_year": 2023,
    "tags": ["Elasticsearch", "实战", "更新"],
    "price": 150.00
    }
    '

2.3.5 删除文档 (Delete Document)

根据文档 ID 删除单个文档。

bash
curl -X DELETE "localhost:9200/books/_doc/1?pretty"

2.3.6 删除索引 (Delete Index)

删除整个索引及其所有文档。

bash
curl -X DELETE "localhost:9200/books?pretty"

三、Elasticsearch 应用开发

在实际应用中,我们通常会使用各种编程语言的客户端库来与 Elasticsearch 交互。以下以 Python 为例,展示如何进行应用开发。

3.1 Python 客户端

安装

bash
pip install elasticsearch

示例代码

“`python
from elasticsearch import Elasticsearch

连接 Elasticsearch 实例

默认连接到 localhost:9200

es = Elasticsearch(
[‘http://localhost:9200′], # 如果有用户名密码,可以这样写:’http://user:password@localhost:9200’
timeout=30 # 设置超时时间
)

1. 检查连接

if es.ping():
print(“Connected to Elasticsearch!”)
else:
print(“Could not connect to Elasticsearch!”)
exit()

index_name = “my_app_articles”

2. 创建索引 (如果不存在)

可以指定 mapping 和 settings

if not es.indices.exists(index=index_name):
es.indices.create(
index=index_name,
body={
“settings”: {
“number_of_shards”: 1,
“number_of_replicas”: 0
},
“mappings”: {
“properties”: {
“title”: {“type”: “text”},
“content”: {“type”: “text”},
“author”: {“type”: “keyword”}, # keyword 类型适用于精确匹配和聚合
“publish_date”: {“type”: “date”},
“views”: {“type”: “integer”}
}
}
}
)
print(f”Index ‘{index_name}’ created.”)
else:
print(f”Index ‘{index_name}’ already exists.”)

3. 索引文档

doc1 = {
“title”: “Elasticsearch入门指南”,
“content”: “这是一篇关于Elasticsearch基础知识的入门指南。”,
“author”: “Alice”,
“publish_date”: “2023-01-15”,
“views”: 150
}
res1 = es.index(index=index_name, id=1, document=doc1)
print(f”Indexed document 1: {res1[‘result’]}”)

doc2 = {
“title”: “Python与Elasticsearch集成”,
“content”: “本文介绍如何使用Python客户端与Elasticsearch进行交互。”,
“author”: “Bob”,
“publish_date”: “2023-02-20”,
“views”: 220
}
res2 = es.index(index=index_name, id=2, document=doc2)
print(f”Indexed document 2: {res2[‘result’]}”)

doc3 = {
“title”: “搜索引擎优化技巧”,
“content”: “了解一些提高网站排名的搜索引擎优化(SEO)技巧。”,
“author”: “Alice”,
“publish_date”: “2023-03-10”,
“views”: 90
}
res3 = es.index(index=index_name, id=3, document=doc3)
print(f”Indexed document 3: {res3[‘result’]}”)

4. 搜索文档

print(“\n— Searching for ‘Elasticsearch’ —“)
search_body = {
“query”: {
“match”: {
“content”: “Elasticsearch”
}
}
}
search_res = es.search(index=index_name, body=search_body)
print(f”Total hits: {search_res[‘hits’][‘total’][‘value’]}”)
for hit in search_res[‘hits’][‘hits’]:
print(f”ID: {hit[‘_id’]}, Source: {hit[‘_source’]}”)

print(“\n— Searching for articles by ‘Alice’ —“)
search_body_author = {
“query”: {
“term”: {
“author.keyword”: “Alice” # 对于 keyword 类型,使用 term 查询进行精确匹配
}
}
}
search_res_author = es.search(index=index_name, body=search_body_author)
print(f”Total hits: {search_res_author[‘hits’][‘total’][‘value’]}”)
for hit in search_res_author[‘hits’][‘hits’]:
print(f”ID: {hit[‘_id’]}, Source: {hit[‘_source’]}”)

5. 更新文档

print(“\n— Updating document 1 views —“)
update_body = {
“script”: {
“source”: “ctx._source.views += params.count”,
“lang”: “painless”,
“params”: {
“count”: 50
}
}
}
update_res = es.update(index=index_name, id=1, body=update_body)
print(f”Updated document 1: {update_res[‘result’]}”)

重新获取文档1查看更新后的 views

updated_doc1 = es.get(index=index_name, id=1)
print(f”Document 1 after update: {updated_doc1[‘_source’]}”)

6. 删除文档

print(“\n— Deleting document 3 —“)

delete_res = es.delete(index=index_name, id=3)

print(f”Deleted document 3: {delete_res[‘result’]}”)

7. 删除索引 (谨慎操作)

print(f”\n— Deleting index ‘{index_name}’ —“)

es.indices.delete(index=index_name, ignore=[400, 404])

print(f”Index ‘{index_name}’ deleted.”)

“`

3.2 进阶应用开发概念

  • 映射 (Mapping):定义文档及其字段的数据类型,以及如何对这些字段进行索引和存储。良好的映射设计是高效搜索的关键。
  • 分析器 (Analyzer):在索引时,文本会被分析器处理成倒排索引中的词条 (term)。分析器由字符过滤器、分词器和 Token 过滤器组成。例如,一个分析器可以将文本转换为小写、去除标点符号,并进行词根提取。
  • 聚合 (Aggregations):ES 强大的数据分析功能。可以对搜索结果进行分组、计数、求和、平均值等操作,类似于 SQL 中的 GROUP BY
    • Metric Aggregations: 如 sum, avg, min, max 等。
    • Bucket Aggregations: 如 terms (按字段值分组), range (按范围分组), date_histogram (按时间间隔分组) 等。
  • 过滤器 (Filters) vs. 查询 (Queries)
    • 查询 (Query Context):用于计算相关性分数 (_score),影响文档的排序。
    • 过滤器 (Filter Context):不计算相关性分数,只判断文档是否匹配。通常比查询快,并且结果可以被缓存。适用于精确匹配、范围查询等不需要评分的场景。
  • 高亮 (Highlighting):在搜索结果中高亮匹配的关键词,提升用户体验。
  • 排序 (Sorting):根据一个或多个字段的值对搜索结果进行排序。
  • 分页 (Pagination):使用 fromsize 参数进行结果分页。

四、总结

本教程从零开始介绍了 Elasticsearch 的核心概念、快速安装方法以及通过 RESTful API 进行的基本操作。随后,我们通过 Python 客户端的示例代码,展示了如何在实际应用中集成 Elasticsearch 进行索引和搜索。

Elasticsearch 不仅仅是一个搜索工具,它更是一个强大的数据平台,可以应用于日志分析、安全智能、业务分析、指标监控等多个领域。通过不断学习其高级特性,如聚合、脚本、插件等,你将能够构建出更加复杂和高效的数据解决方案。

希望本教程能帮助你迈出 Elasticsearch 学习的第一步,开启你的数据搜索与分析之旅!

滚动至顶部