elasticsearch 默认配置搜不出中文结果,因standard分词器将“搜索引擎”切为单字,需用ik_max_word等中文分词器并重建索引。

为什么直接用 elasticsearch-py 默认配置搜不出结果
刚连上 Elasticsearch,search() 返回空 hits,不是数据没索引,而是默认 match 查询对中文分词失效。Elasticsearch 原生不支持中文分词,standard 分析器会把“搜索引擎”切为单字,导致无法匹配完整词项。
必须显式指定中文分词器(如 ik_max_word)并确保索引创建时已绑定:
{
"settings": {
"analysis": {
"analyzer": {
"my_ik_analyzer": {
"type": "custom",
"tokenizer": "ik_max_word"
}
}
}
},
"mappings": {
"properties": {
"title": { "type": "text", "analyzer": "my_ik_analyzer" },
"content": { "type": "text", "analyzer": "my_ik_analyzer" }
}
}
}
- 别在已有索引上改
analyzer—— 必须重建索引,旧数据需 reindex - 确认 IK 插件已安装:
curl -X GET "localhost:9200/_cat/plugins?v" | grep ik - Python 中发请求前,先用
es.indices.get(index="your_index")验证 mapping 是否生效
如何让 Web 请求响应压到 50ms 内
毫秒级不是靠堆硬件,关键在三处:查询精简、缓存绕过、连接复用。
- 禁用
explain和profile:Web 查询绝不带这两个参数,它们会让耗时翻 3–5 倍 - 用
filter替代query做结构化条件(如时间范围、状态码):filter 结果可被缓存,且不计算相关度 - Python 客户端必须复用
Elasticsearch实例,别每次请求都 new 一个 —— 连接池和长连接能省掉 20–40ms 建连开销 - 限制返回字段:
_source=["title", "url"],避免传输冗余内容;size别设太大,默认 10 足够,前端分页靠from/size或游标
multi_match 怎么配权重才不偏科
搜“python 教程”,如果 title 字段匹配了但 content 没匹配,结果可能排后面——因为默认各字段等权,而 content 更长、TF-IDF 值天然偏低。
用 fields 显式加权:
{
"query": {
"multi_match": {
"query": "python 教程",
"fields": ["title^3", "content^1", "tags^2"]
}
}
}
-
^3表示该字段得分乘以 3,不是“优先查”,是“算分时权重高” - 别滥用高权重:title^10 会导致 content 匹配再好也难进前几,实际调参建议从 ^2 开始试
- 若字段类型是
keyword(如 status),不能参与multi_match,会报错all shards failed
为什么 Python 异步发请求反而更慢
用 aiohttp 或 asyncio 封装 elasticsearch-py?别费劲——官方客户端底层基于 urllib3,本身已做连接池和复用,同步调用在单次请求下比异步还快 5–10ms。
- 真正要异步的场景:一次 Web 请求需查多个索引(如用户+订单+日志),这时用
asyncio.gather()并发调es.search() - 单索引单查,同步
es.search()最稳;强行套loop.run_in_executor只会引入线程切换开销 - 如果你用 FastAPI,直接依赖注入一个全局
Elasticsearch实例即可,它本身是线程安全的
最常被忽略的是:没关掉 Elasticsearch 的慢日志(index.search.slowlog.threshold.query.warn 设为 -1),日志刷盘会拖慢真实响应,线上务必关掉。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











