Elasticsearch 快速入门 - Python版本

🏆 简介

本教程将带你从0到1掌握Elasticsearch的核心操作,通过知识点解析+代码示例的形式,让你轻松理解并应用Elasticsearch。教程基于Elasticsearch 6.x版本,内容涵盖从基础连接到高级查询的完整知识体系。

📚 目录

  1. 环境准备与基础连接

    • 安装依赖
    • 连接Elasticsearch
    • 测试连接状态
  2. 索引管理

    • 索引概念
    • 创建索引
    • 修改索引设置
    • 索引别名管理
  3. 文档CRUD操作

    • 单个文档操作
    • 批量操作
    • 数据查询
  4. 零停机索引迁移

    • 迁移原理
    • 实现步骤
    • 原子切换
  5. 高级查询技巧

    • 分页查询
    • 排序查询
    • 复合查询
    • 全文搜索

1. 环境准备与基础连接

1.1 安装依赖

知识点: Elasticsearch提供了官方的Python客户端库,通过pip安装后可以方便地与Elasticsearch服务器交互。

安装命令:

bash 复制代码
pip install elasticsearch

1.2 连接Elasticsearch

知识点: 使用Elasticsearch类创建连接客户端,需要指定Elasticsearch服务器的主机地址和端口。支持多个节点的连接配置,以提高系统的可用性。

代码示例:

python 复制代码
from elasticsearch import Elasticsearch

# 连接到单节点Elasticsearch
es = Elasticsearch([{"host": "localhost", "port": 9200}])

# 连接到多节点Elasticsearch(生产环境推荐)
es = Elasticsearch([
    {"host": "es-node1", "port": 9200},
    {"host": "es-node2", "port": 9200},
    {"host": "es-node3", "port": 9200}
])

1.3 测试连接状态

知识点: 连接Elasticsearch后,应测试连接是否成功。可以通过info()方法获取Elasticsearch服务器信息,或使用ping()方法快速检查连接状态。

代码示例:

python 复制代码
# 获取Elasticsearch服务器信息
info = es.info()
print(f"Elasticsearch版本: {info['version']['number']}")
print(f"集群名称: {info['cluster_name']}")

# 快速测试连接是否可用
if es.ping():
    print("✅ 连接成功!")
else:
    print("❌ 连接失败!")

2. 索引管理

2.1 索引概念

知识点: 索引(Index)是Elasticsearch中存储数据的基本单位,类似于关系数据库中的数据库。每个索引都有自己的映射(Mapping)和设置(Settings):

  • Mapping: 定义文档的结构和字段类型
  • Settings: 配置索引的性能参数(如分片数、副本数等)

2.2 创建索引

知识点: 创建索引时需要定义映射结构和索引设置。映射定义了文档中每个字段的数据类型,设置定义了索引的性能参数。

代码示例:

python 复制代码
# 定义索引名称
index_name = "my_index"

# 定义索引结构
index_body = {
    "settings": {
        "index": {
            "number_of_shards": 3,    # 分片数
            "number_of_replicas": 1   # 副本数
        }
    },
    "mappings": {
        "_doc": {  # ES 6.x版本需要指定type为_doc
            "properties": {
                "title": {"type": "text"},        # 全文本字段
                "author": {"type": "keyword"},    # 关键词字段(精确匹配)
                "publish_date": {"type": "date"},  # 日期字段
                "views": {"type": "integer"},     # 整数字段
                "price": {"type": "float"}        # 浮点数字段
            }
        }
    }
}

# 创建索引
es.indices.create(index=index_name, body=index_body)
print(f"✅ 索引 '{index_name}' 创建成功!")

2.3 检查与删除索引

知识点: 在创建索引前,通常需要检查索引是否已存在;当不再需要索引时,可以删除索引以释放资源。

代码示例:

python 复制代码
# 检查索引是否存在
if es.indices.exists(index=index_name):
    print(f"索引 '{index_name}' 已存在")
    
    # 删除索引
    es.indices.delete(index=index_name)
    print(f"索引 '{index_name}' 已删除")

2.4 修改索引设置

知识点: 创建索引后,可以修改部分索引设置,如副本数。但分片数等核心设置在创建后无法修改。

代码示例:

python 复制代码
# 修改索引的副本数
es.indices.put_settings(
    index=index_name,
    body={"settings": {"index": {"number_of_replicas": 2}}}
)
print(f"✅ 索引 '{index_name}' 的副本数已修改为2")

2.5 修改映射结构

知识点: 索引创建后,可以向映射中添加新字段,但不能修改现有字段的数据类型(除非重建索引)。

代码示例:

python 复制代码
# 向映射中添加新字段
es.indices.put_mapping(
    index=index_name,
    doc_type="_doc",
    body={"properties": {"tags": {"type": "keyword"}}}
)
print(f"✅ 索引 '{index_name}' 的映射已添加新字段'tags'")

2.6 索引别名管理

知识点: 索引别名是指向一个或多个索引的引用,可以随时更改别名指向的索引,从而实现零停机维护。

代码示例:

python 复制代码
# 添加索引别名
alias_name = "my_index_alias"
es.indices.put_alias(index=index_name, name=alias_name)
print(f"✅ 已为索引 '{index_name}' 添加别名 '{alias_name}'")

# 获取索引的所有别名
aliases = es.indices.get_alias(index=index_name)
print(f"索引 '{index_name}' 的别名:{list(aliases[index_name]['aliases'].keys())}")

# 删除索引别名
es.indices.delete_alias(index=index_name, name=alias_name)
print(f"✅ 已删除索引 '{index_name}' 的别名 '{alias_name}'")

3. 文档CRUD操作

3.1 单个文档操作

3.1.1 创建文档

知识点: 可以通过指定ID创建文档,也可以让Elasticsearch自动生成ID。创建文档时,如果ID已存在,则会覆盖现有文档。

代码示例:

python 复制代码
# 指定ID创建文档
doc_id = "1"
doc = {
    "title": "Elasticsearch实战教程",
    "author": "张三",
    "publish_date": "2024-01-15",
    "views": 1000,
    "price": 99.9
}

# 使用index方法创建文档
es.index(index=index_name, doc_type="_doc", id=doc_id, body=doc)
print(f"✅ 文档已创建,ID: {doc_id}")

3.1.2 查询文档

知识点: 可以通过ID查询单个文档,也可以使用搜索API查询多个文档。

代码示例:

python 复制代码
# 根据ID查询文档
res = es.get(index=index_name, doc_type="_doc", id=doc_id)
print(f"📄 查询结果:{res['_source']}")

# 查询所有文档
res = es.search(index=index_name, body={"query": {"match_all": {}}})
print(f"📊 共找到 {res['hits']['total']} 条文档")

3.1.3 更新文档

知识点: 更新文档时,可以更新整个文档,也可以只更新部分字段。Elasticsearch会先检索文档,然后更新它,最后重新索引。

代码示例:

python 复制代码
# 部分更新文档
es.update(
    index=index_name,
    doc_type="_doc",
    id=doc_id,
    body={"doc": {"views": 1500, "price": 89.9}}
)
print(f"✅ 文档 '{doc_id}' 已更新")

3.1.4 删除文档

知识点: 可以通过ID删除单个文档,也可以使用删除查询API删除符合条件的多个文档。

代码示例:

python 复制代码
# 根据ID删除文档
es.delete(index=index_name, doc_type="_doc", id=doc_id)
print(f"✅ 文档 '{doc_id}' 已删除")

3.2 批量操作

知识点: 批量操作可以提高处理大量文档时的性能,减少网络往返次数。Elasticsearch提供了helpers.bulk()方法来简化批量操作。

代码示例:

python 复制代码
from elasticsearch import helpers

# 准备批量操作数据
actions = [
    {
        "_index": index_name,
        "_type": "_doc",
        "_id": str(i+1),
        "_source": {
            "title": f"文档 {i+1}",
            "author": "作者",
            "views": (i+1)*100
        }
    }
    for i in range(5)
]

# 执行批量索引操作
helpers.bulk(es, actions)
print(f"✅ 已批量索引 {len(actions)} 条文档")

3.3 数据查询

3.3.1 基本查询

知识点: Elasticsearch提供了丰富的查询功能,包括精确查询、范围查询、模糊查询等。查询条件通过JSON格式的查询体定义。

代码示例:

python 复制代码
# 精确匹配查询
res = es.search(
    index=index_name,
    body={
        "query": {
            "term": {"author": "张三"}
        }
    }
)
print(f"🔍 找到 {res['hits']['total']} 条匹配文档")

# 范围查询
res = es.search(
    index=index_name,
    body={
        "query": {
            "range": {
                "views": {"gte": 500, "lte": 2000}
            }
        }
    }
)
print(f"🔍 找到 {res['hits']['total']} 条浏览量在500-2000之间的文档")

3.3.2 复合查询

知识点: 复合查询允许组合多个查询条件,使用布尔逻辑(must、should、must_not)来构建复杂查询。

代码示例:

python 复制代码
# 布尔复合查询
res = es.search(
    index=index_name,
    body={
        "query": {
            "bool": {
                "must": [  # 必须满足的条件
                    {"term": {"author": "张三"}},
                    {"range": {"views": {"gt": 1000}}}
                ],
                "filter": [  # 过滤条件(不影响评分)
                    {"range": {"price": {"lt": 100}}}
                ]
            }
        }
    }
)
print(f"🔍 找到 {res['hits']['total']} 条符合所有条件的文档")

4. 零停机索引迁移

4.1 迁移原理

知识点: 零停机索引迁移是指在不中断服务的情况下,将数据从一个索引迁移到另一个索引。这在需要修改索引结构(如字段类型)时非常有用。主要通过索引别名和原子切换实现。

4.2 实现步骤

知识点: 零停机迁移的核心步骤包括:创建新索引、数据迁移、原子切换别名。

代码示例:

python 复制代码
# 定义旧索引、新索引和别名
old_index = "products_v1"
new_index = "products_v2"
write_alias = "products_write"
read_alias = "products_read"

# 1. 创建新索引(修改映射结构)
es.indices.create(
    index=new_index,
    body={
        "settings": {"index": {"number_of_shards": 3, "number_of_replicas": 1}},
        "mappings": {
            "_doc": {
                "properties": {
                    # 新的映射结构,可以修改字段类型等
                    "name": {"type": "text"},
                    "price": {"type": "scaled_float", "scaling_factor": 100}  # 修复精度问题
                }
            }
        }
    }
)

# 2. 数据迁移:从旧索引复制数据到新索引
es.reindex(
    body={"source": {"index": old_index}, "dest": {"index": new_index}},
    wait_for_completion=True  # 同步执行
)
print(f"🚚 数据已从 '{old_index}' 迁移到 '{new_index}'")

4.3 原子切换

知识点: 原子切换是零停机迁移的关键步骤,通过update_aliasesAPI在一个原子操作中完成别名的移除和添加,确保服务不中断。

代码示例:

python 复制代码
# 3. 原子性切换别名
es.indices.update_aliases(
    body={
        "actions": [
            {"remove": {"index": old_index, "alias": write_alias}},
            {"add": {"index": new_index, "alias": write_alias}},
            {"remove": {"index": old_index, "alias": read_alias}},
            {"add": {"index": new_index, "alias": read_alias}}
        ]
    }
)
print(f"✅ 已原子性切换别名到新索引 '{new_index}'")

# 4. 验证:通过别名查询数据
res = es.search(index=read_alias, body={"query": {"match_all": {}}})
print(f"📊 通过别名查询到 {res['hits']['total']} 条记录")

5. 高级查询技巧

5.1 分页查询

知识点: 当查询结果较多时,需要使用分页功能。Elasticsearch通过fromsize参数实现分页,from指定起始位置,size指定每页记录数。

代码示例:

python 复制代码
# 分页查询:第1页,每页10条
page = 1
page_size = 10
from_pos = (page - 1) * page_size

res = es.search(
    index=index_name,
    body={
        "query": {"match_all": {}},
        "from": from_pos,
        "size": page_size
    }
)
print(f"📄 第{page}页,共找到 {res['hits']['total']} 条记录,本页有 {len(res['hits']['hits'])} 条")

5.2 排序查询

知识点: Elasticsearch支持对查询结果进行排序,可以按单个字段排序,也可以按多个字段排序。

代码示例:

python 复制代码
# 按单个字段排序(价格升序)
res = es.search(
    index=index_name,
    body={
        "query": {"match_all": {}},
        "sort": [{"price": {"order": "asc"}}]
    }
)
print("🔀 按价格升序排序结果:")
for hit in res['hits']['hits']:
    print(f"  - {hit['_source']['title']}: {hit['_source']['price']}元")

# 按多个字段排序(先按分类,再按价格降序)
res = es.search(
    index=index_name,
    body={
        "query": {"match_all": {}},
        "sort": [
            {"category": {"order": "asc"}},
            {"price": {"order": "desc"}}
        ]
    }
)

5.3 聚合查询

知识点: 聚合查询用于对数据进行统计分析,可以实现分组、求和、平均值等统计功能。

代码示例:

python 复制代码
# 按分类分组并统计数量
res = es.search(
    index=index_name,
    body={
        "size": 0,  # 不返回原始文档
        "aggs": {
            "category_count": {
                "terms": {"field": "category.keyword"}
            }
        }
    }
)
print("📊 按分类统计:")
for bucket in res['aggregations']['category_count']['buckets']:
    print(f"  - {bucket['key']}: {bucket['doc_count']} 件")

# 计算平均价格
res = es.search(
    index=index_name,
    body={
        "size": 0,
        "aggs": {
            "avg_price": {
                "avg": {"field": "price"}
            }
        }
    }
)
print(f"💰 平均价格: {res['aggregations']['avg_price']['value']:.2f} 元")

5.4 全文搜索

知识点: 全文搜索是Elasticsearch的核心功能,可以对文本字段进行分词搜索,并根据相关性评分返回结果。

代码示例:

python 复制代码
# 基本全文搜索
res = es.search(
    index=index_name,
    body={
        "query": {
            "match": {
                "title": "Elasticsearch教程"
            }
        }
    }
)
print(f"🔍 找到 {res['hits']['total']} 条匹配'Elasticsearch教程'的记录")

# 多字段全文搜索
res = es.search(
    index=index_name,
    body={
        "query": {
            "multi_match": {
                "query": "入门指南",
                "fields": ["title", "description"]
            }
        }
    }
)
print(f"🔍 在多个字段中找到 {res['hits']['total']} 条匹配'入门指南'的记录")

🎯 总结与建议

通过本教程,你已经学习了Elasticsearch的核心操作,包括:

  1. 基础连接 - 如何连接Elasticsearch并测试连接状态
  2. 索引管理 - 如何创建、修改和管理索引
  3. 文档操作 - 如何进行文档的增删改查和批量操作
  4. 零停机迁移 - 如何在不中断服务的情况下更新索引结构
  5. 高级查询 - 如何使用分页、排序、聚合和全文搜索功能

希望本教程能帮助你快速掌握Elasticsearch的使用技巧,祝你在搜索的世界里探索愉快!


🌟 如果你觉得本教程对你有帮助,请给我一个赞!如有任何问题或建议,欢迎留言讨论。

相关推荐
道可到2 小时前
Java 面试通关笔记 01|拆箱与装箱:你真的理解了吗?
后端·面试
王彦臻2 小时前
PyTorch 中模型测试与全局平均池化的应用总结
人工智能·pytorch·python
C++chaofan2 小时前
通过Selenium实现网页截图来生成应用封面
java·spring boot·后端·selenium·测试工具·编程·截图
Java水解3 小时前
MySQL常用客户端工具详解
后端·mysql
Olaf_n3 小时前
SpringBoot自动装配
spring boot·后端·程序员
_码力全开_3 小时前
Python从入门到实战 (14):工具落地:用 PyInstaller 打包 Python 脚本为可执行文件
开发语言·数据结构·python·个人开发
我是前端小学生3 小时前
从solana安装脚本中学习的知识
后端
开心-开心急了4 小时前
PySide6实时检测剪贴板(QClipboard)并更新文本
python·ui·pyqt