ElasticSearch 从入门到“真香”指南(终极详细版)
副标题:从“LIKE %% 暴君”到“搜索之王”,你只差这一篇!(内含脱发警告⚠️)
1. 前言:为什么说ES是程序员的“第二春”?
1.1 惨案回顾:那些年被SQL模糊搜索支配的恐惧
-- 产品经理的“简单需求”
SELECT * FROM products
WHERE name LIKE '%手机%'
OR description LIKE '%智能%'
OR tags LIKE '%折扣%';
-- 执行结果:数据库CPU 100%,查询耗时58秒,你被拉进会议室“喝茶”
1.2 ES的“超能力”清单
- 速度:毫秒级搜索(比女朋友变脸还快)
- 扩展性:横向扩容像乐高积木(没钱就加机器,简单粗暴)
- 功能:分词/聚合/拼音/纠错/高亮...(瑞士军刀看了都沉默)
- 适用场景:日志分析、商品搜索、智能推荐、甚至帮你找对象(误)
2. 安装部署:从“Hello World”到“分布式集群”
2.1 单机版安装(5分钟装X指南)
2.1.1 Docker极简版(适合只想试试水的)
docker run -d --name elasticsearch \
-p 9200:9200 -p 9300:9300 \
-e "discovery.type=single-node" \
elasticsearch:7.14.0
验证成功:
curl http://localhost:9200
# 看到 {"name": "节点名", "cluster_name": "elasticsearch", "tagline": "You Know, for Search"} ?恭喜,ES对你说了第一句情话!
2.1.2 物理机部署(生产环境必看)
# 1. 下载并解压(建议用国内镜像,否则速度比蜗牛还慢)
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.14.0-linux-x86_64.tar.gz
tar -zxvf elasticsearch-7.14.0-linux-x86_64.tar.gz
# 2. 调整JVM参数(重要!否则内存爆炸)
vim config/jvm.options
-Xms2g # 最小内存(建议和Xmx一致,防止抖动)
-Xmx2g # 最大内存(别超过物理内存的50%!)
# 3. 启动!(记得用非root用户,否则ES会傲娇拒绝)
./bin/elasticsearch
2.2 集群搭建(从“单身狗”到“兄弟连”)
# config/elasticsearch.yml 配置示例:
cluster.name: my-es-cluster # 集群名(中二点,比如“灭霸军团”)
node.name: node-1 # 节点名(建议按功能命名,如“node-data-1”)
network.host: 0.0.0.0 # 监听地址(谨慎开放!)
discovery.seed_hosts: ["192.168.1.101", "192.168.1.102"] # 其他节点IP
cluster.initial_master_nodes: ["node-1", "node-2"] # 初始主节点
集群健康检查:
GET /_cluster/health
# 响应中的 "status" 字段:
# - green:健康(理想状态)
# - yellow:部分副本未分配(钱包在哭泣)
# - red:有主分片丢失(赶紧跑路!)
3. 核心概念:ES世界的“生存法则”
3.1 索引(Index)—— 数据的“主题酒店”
- 定义:类似MySQL的表,但更灵活(不需要提前定义所有字段)
- 冷知识:索引名字必须全小写!(否则ES会像甲方一样无情报错)
3.2 文档(Document)—— 数据的“身份证”
{
"_index": "user", // 住在哪个“酒店”
"_id": "666", // 身份证号(不指定则ES自动生成)
"_source": { // 真实数据
"name": "李狗蛋",
"age": 28,
"hobby": ["写BUG", "修BUG"]
}
}
3.3 倒排索引(Inverted Index)—— ES的“核武器”
传统数据库:
文档1 → 内容:"我爱写Java"
文档2 → 内容:"我爱写Python"
倒排索引:
"我" → [文档1, 文档2]
"爱" → [文档1, 文档2]
"Java" → [文档1]
"Python" → [文档2]
比喻:就像把一本书撕成单词,再给每个单词记下出现的页码——找东西快到飞起!
4. 增删改查:和ES的“爱恨情仇”
4.1 创建索引(小心!这不是MySQL)
PUT /my_index
{
"settings": {
"number_of_shards": 3, // 主分片数(一旦设定,终身不能改!)
"number_of_replicas": 1 // 副本数(随时可调,建议生产环境≥1)
},
"mappings": { // 字段类型定义(类似表结构)
"properties": {
"title": { "type": "text" }, // 文本类型(会被分词)
"price": { "type": "double" }, // 数字类型(适合范围查询)
"tags": { "type": "keyword" } // 关键字类型(精确匹配)
}
}
}
4.2 插入文档(ES的“朋友圈”)
POST /my_index/_doc/1 // 指定ID=1
{
"title": "程序员防脱发指南",
"price": 0.99, // 知识无价,但这里标价0.99
"tags": ["养生", "科技"]
}
POST /my_index/_doc // 不指定ID,ES自动生成(类似UUID)
{
"title": "如何在996中保持微笑",
"price": 9.9,
"tags": ["职场", "心理学"]
}
4.3 复杂查询(ES的“高光时刻”)
4.3.1 组合查询:must(且)、should(或)
GET /my_index/_search
{
"query": {
"bool": {
"must": [ // 必须满足
{ "match": { "title": "程序员" } }
],
"should": [ // 满足加分
{ "range": { "price": { "lte": 10 } } }, // 价格≤10
{ "term": { "tags": "养生" } } // 精确匹配标签
]
}
}
}
4.3.2 高亮显示(让关键词“发光”)
{
"highlight": {
"fields": {
"title": {} // 对title字段高亮
}
}
}
// 响应片段:
"highlight": {
"title": ["<em>程序员</em>防脱发指南"]
}
5. 高级玩法:让ES为你“996”
5.1 中文分词器(告别“中国式”尴尬)
默认分词问题:
POST /_analyze
{
"text": "南京市长江大桥"
}
# 分词结果:["南", "京", "市", "长", "江", "大", "桥"] (惨不忍睹)
安装IK分词器:
# 进入ES容器安装
bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.14.0/elasticsearch-analysis-ik-7.14.0.zip
效果验证:
POST /_analyze
{
"analyzer": "ik_max_word",
"text": "南京市长江大桥"
}
# 分词结果:["南京市", "长江大桥", "大桥"] (舒服了!)
5.2 聚合分析(老板的最爱)
5.2.1 统计每个标签的商品数量
{
"aggs": {
"tag_count": {
"terms": { "field": "tags.keyword" }
}
}
}
// 结果示例:
"buckets": [
{ "key": "养生", "doc_count": 100 },
{ "key": "科技", "doc_count": 80 }
]
5.2.2 计算价格区间分布
{
"aggs": {
"price_stats": {
"histogram": {
"field": "price",
"interval": 10 // 每10元一个区间
}
}
}
}
6. 性能优化:从“蜗牛”到“猎豹”
6.1 硬件配置黄金法则
- 内存:至少64GB(ES是内存狂魔)
- 磁盘:SSD!SSD!SSD!(重要的事情说三遍)
- CPU:核心越多越好(但别和GPU搞混了)
6.2 调参大师的秘籍
# config/elasticsearch.yml 优化项:
indices.query.bool.max_clause_count: 1024 # 提高布尔查询子句数限制
thread_pool.search.size: 100 # 增加搜索线程池大小
6.3 冷热数据分离(省钱妙招)
- 热节点:SSD盘,存放近期高频访问数据(如当天日志)
- 冷节点:机械硬盘,存放历史归档数据(如3年前的日志)
7. 灾难恢复:别等到删库才流泪
7.1 快照备份(ES的“后悔药”)
# 创建仓库
PUT /_snapshot/my_backup
{
"type": "fs",
"settings": { "location": "/mnt/es_backups" }
}
# 手动备份
PUT /_snapshot/my_backup/snapshot_1?wait_for_completion=true
{
"indices": "my_index", // 指定要备份的索引
"ignore_unavailable": true
}
7.2 数据恢复(最后的救命稻草)
POST /_snapshot/my_backup/snapshot_1/_restore
{
"indices": "my_index",
"rename_pattern": "my_index",
"rename_replacement": "restored_my_index" // 恢复为新索引
}
8. 结语:你与ES的“未来”
掌握ES后,你将获得:
- 应对产品经理的“底气”(“这个需求,加个ES就能搞定!”)
- 简历上的“亮点”(“精通分布式搜索”)
- 告别
LIKE %%
的快乐(数据库再也不会半夜报警)
最后友情提醒:
如果学习ES过程中出现以下症状:
- 凌晨3点还在调试分词器
- 梦见自己变成了一个文档被索引 —— 恭喜,你已正式“入坑”搜索领域!🎉