Elasticsearch 8.x + Python 官方客户端实战教程

Elasticsearch 8.x + Python 官方客户端实战教程

一、Elasticsearch 基础概念(工程视角)

1. Index(索引)

  • 类似 数据库中的表
  • 一个 Index 通常对应一个业务实体集合,例如:
    • user_logs
    • order_records

⚠️ 工程建议

  • 一个索引只服务一种查询模式
  • 不要把"所有数据"塞进一个 index

2. Document(文档)

  • 一条 JSON 数据
  • 每条文档都有 _id
json 复制代码
{
  "user_id": "u123",
  "action": "login",
  "timestamp": "2025-01-01T10:00:00"
}

3. Mapping(字段结构)

  • 相当于 表结构定义
  • 决定:
    • 是否可搜索
    • 是否可聚合
    • 是否支持排序

一旦字段类型确定,几乎不可修改


4. Shard / Replica(分片 & 副本)

  • shard:数据拆分单元(影响写入 & 查询性能)
  • replica:副本(高可用 & 查询吞吐)

通用建议:

  • 中小业务:1~3 shards
  • 副本数:1

二、Elasticsearch 8.x 架构与安全机制

8.x 开始默认开启安全机制

  • HTTPS
  • 用户认证
  • API 访问权限

👉 Python 客户端必须显式配置认证


三、Python 官方客户端安装(8.x)

bash 复制代码
pip install elasticsearch>=8.12.0

验证版本:

python 复制代码
from elasticsearch import __version__
print(__version__)

四、Python 连接 Elasticsearch(生产可用)

1. 基础连接(用户名 + 密码)

python 复制代码
from elasticsearch import Elasticsearch

es = Elasticsearch(
    hosts=["https://localhost:9200"],
    basic_auth=("elastic", "your_password"),
    verify_certs=False  # 本地测试可关闭,生产请开启
)

print(es.info())

2. HTTPS + CA 证书(生产推荐)

python 复制代码
es = Elasticsearch(
    hosts=["https://es-prod.example.com:9200"],
    basic_auth=("elastic", "password"),
    ca_certs="/etc/elasticsearch/certs/http_ca.crt"
)

五、索引设计与创建(真实工程示例)

1. 索引 Mapping 设计

python 复制代码
INDEX_NAME = "user_action_logs"

mapping = {
    "settings": {
        "number_of_shards": 2,
        "number_of_replicas": 1
    },
    "mappings": {
        "properties": {
            "user_id": {"type": "keyword"},
            "action": {"type": "keyword"},
            "message": {"type": "text"},
            "ip": {"type": "ip"},
            "created_at": {"type": "date"}
        }
    }
}

2. 创建索引(幂等)

python 复制代码
if not es.indices.exists(index=INDEX_NAME):
    es.indices.create(index=INDEX_NAME, body=mapping)

六、数据写入(单条 & 批量)

1. 单条写入(index)

python 复制代码
es.index(
    index=INDEX_NAME,
    id="u123_001",
    document={
        "user_id": "u123",
        "action": "login",
        "message": "user login success",
        "ip": "127.0.0.1",
        "created_at": "2025-01-01T10:00:00"
    }
)

2. 批量写入(bulk,生产必用)

python 复制代码
from elasticsearch.helpers import bulk

actions = []
for i in range(1000):
    actions.append({
        "_index": INDEX_NAME,
        "_id": f"u123_{i}",
        "_source": {
            "user_id": "u123",
            "action": "click",
            "message": f"click {i}",
            "ip": "127.0.0.1",
            "created_at": "2025-01-01T10:00:00"
        }
    })

bulk(es, actions, request_timeout=60)

工程建议

  • 单批 500~2000 条
  • 明确 _id,保证幂等

七、查询(核心能力)

1. 基础查询

python 复制代码
res = es.search(
    index=INDEX_NAME,
    query={
        "term": {"action": "login"}
    }
)

2. Bool 查询(真实业务)

python 复制代码
res = es.search(
    index=INDEX_NAME,
    query={
        "bool": {
            "must": [
                {"term": {"user_id": "u123"}}
            ],
            "filter": [
                {"range": {"created_at": {"gte": "now-1d"}}}
            ]
        }
    },
    size=20,
    sort=[{"created_at": "desc"}]
)

3. 聚合查询

python 复制代码
res = es.search(
    index=INDEX_NAME,
    size=0,
    aggs={
        "action_count": {
            "terms": {"field": "action"}
        }
    }
)

八、深分页解决方案

❌ from + size(禁止大页)

  • 超过 10k 会严重影响性能

search_after(推荐)

python 复制代码
res = es.search(
    index=INDEX_NAME,
    size=10,
    sort=[
        {"created_at": "desc"},
        {"_id": "desc"}
    ]
)

last_sort = res["hits"]["hits"][-1]["sort"]

res_next = es.search(
    index=INDEX_NAME,
    size=10,
    search_after=last_sort,
    sort=[
        {"created_at": "desc"},
        {"_id": "desc"}
    ]
)

九、工程级 Client 封装示例

python 复制代码
class ESClient:
    def __init__(self, hosts, username, password, ca_certs=None):
        self.client = Elasticsearch(
            hosts=hosts,
            basic_auth=(username, password),
            ca_certs=ca_certs,
        )

    def index_doc(self, index, doc_id, doc):
        return self.client.index(index=index, id=doc_id, document=doc)

    def search(self, index, query, size=10):
        return self.client.search(index=index, query=query, size=size)

十、常见踩坑总结(8.x)

  1. ❌ 使用 body= 写 search(已废弃)
  2. ❌ 忽略 HTTPS / 认证
  3. ❌ 动态 Mapping 失控
  4. ❌ 大分页 from + size

十一、结语

如果你:

  • 正确设计索引
  • 使用 bulk 写入
  • 使用 bool + filter 查询
  • 合理分页
相关推荐
2401_841495648 小时前
【自然语言处理】中文文本字频统计与交互式可视化工具
人工智能·python·自然语言处理·多线程·分块读取·文本分析·字频统计
wang6021252188 小时前
FastAPI的异步开发-Asyncio
python·fastapi·asyncio
AI视觉网奇8 小时前
Meta-Llama-3.1-8B-bnb-4bit 下载加载
linux·开发语言·python
if时光重来8 小时前
kingbase数据库指定数据表自增id重置
数据库·python·sql
赵谨言8 小时前
基于OpenCV的人脸五官识别系统研究
大数据·开发语言·经验分享·python
2401_841495648 小时前
【自然语言处理】处理 GBK 编码汉字的算法设计
人工智能·python·自然语言处理·校验·文件读写·gbk编码与解码·批量过滤
俊俊谢8 小时前
【机器学习】python使用支持向量机解决兵王问题(基于libsvm库)
python·机器学习·支持向量机·svm·libsvm
爱笑的眼睛118 小时前
MLflow Tracking API:超越实验记录,构建可复现的机器学习工作流
java·人工智能·python·ai