当前位置: 首页 > news >正文

ElasticSearch复习指南:从零搭建一个商品搜索案例

前言:为什么我们需要ElasticSearch?

想象一下,你正在开发一个电商网站,商品数量达到百万级别。用户需要能够快速搜索商品,并且希望支持模糊匹配、按价格筛选、按分类过滤等功能。

如果使用传统的数据库(如MySQL)来实现,你可能会写出这样的查询:

SELECT * FROM products 
WHERE name LIKE '%手机%' 
AND price BETWEEN 1000 AND 5000 
AND category_id = 1
ORDER BY create_time DESC
LIMIT 20 OFFSET 0;

随着数据量增加,这种查询会变得越来越慢,而且无法很好地支持模糊搜索和相关度排序。这就是ElasticSearch的用武之地。

一、ElasticSearch核心概念快速回顾

1.1 倒排索引:为什么ES这么快?

传统数据库使用"正排索引":文档→关键词

文档1:我爱学习ElasticSearch
文档2:ElasticSearch真强大

而ElasticSearch使用"倒排索引":关键词→文档

我: [文档1]
爱: [文档1]
学习: [文档1]
ElasticSearch: [文档1, 文档2]
真: [文档2]
强大: [文档2]

这样搜索"ElasticSearch"时,直接就能找到文档1和文档2,无需扫描所有文档。

1.2 基本概念对照表

ElasticSearch术语传统数据库类比说明
Index(索引)Database(数据库)数据容器
Type(类型)Table(表)ES7+已废弃
Document(文档)Row(行)基本数据单位
Field(字段)Column(列)数据字段
Mapping(映射)Schema(模式)数据结构定义

二、实战案例:搭建商品搜索系统

让我们通过一个真实案例来复习ElasticSearch的使用。

2.1 环境准备

首先使用Docker启动ElasticSearch和Kibana:

# 启动ElasticSearch
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.17.0# 启动Kibana(Web管理界面)
docker run -d --name kibana --link elasticsearch:elasticsearch -p 5601:5601 kibana:7.17.0

2.2 创建商品索引

假设我们的商品有以下字段:

  • id:商品ID
  • name:商品名称
  • price:价格
  • category:分类
  • description:描述
  • tags:标签数组
PUT /products
{"mappings": {"properties": {"id": { "type": "integer" },"name": { "type": "text","analyzer": "ik_max_word",  // 使用中文分词器"search_analyzer": "ik_smart"},"price": { "type": "float" },"category": { "type": "keyword" },"description": { "type": "text","analyzer": "ik_max_word"},"tags": { "type": "keyword" },"created_at": { "type": "date" }}}
}

2.3 插入测试数据

POST /products/_bulk
{"index":{"_id":1}}
{"id":1,"name":"Apple iPhone 13","price":5999,"category":"手机","description":"新一代iPhone,A15芯片,超视网膜XDR显示屏","tags":["苹果","智能手机","5G"],"created_at":"2022-01-01"}
{"index":{"_id":2}}
{"id":2,"name":"华为Mate 50","price":5499,"category":"手机","description":"华为旗舰手机,鸿蒙系统,超强拍照","tags":["华为","智能手机","5G"],"created_at":"2022-02-01"}
{"index":{"_id":3}}
{"id":3,"name":"小米手环7","price":249,"category":"智能穿戴","description":"1.62英寸AMOLED屏,120种运动模式","tags":["小米","智能手环","健康监测"],"created_at":"2022-03-01"}

2.4 实现复杂搜索功能

​案例1:基本搜索​​ - 查找商品名称或描述中包含"手机"的商品

GET /products/_search
{"query": {"multi_match": {"query": "手机","fields": ["name", "description"]}}
}

​案例2:多条件过滤​​ - 搜索手机分类中,价格在5000-6000之间的商品

GET /products/_search
{"query": {"bool": {"must": [{ "match": { "category": "手机" } }],"filter": [{ "range": { "price": { "gte": 5000, "lte": 6000 } } }]}}
}

​案例3:模糊搜索与评分​​ - 搜索"华为"(用户输入错误)

GET /products/_search
{"query": {"fuzzy": {"name": {"value": "华为","fuzziness": "AUTO"}}}
}

​案例4:聚合分析​​ - 统计每个分类的商品数量和平均价格

GET /products/_search
{"size": 0,"aggs": {"categories": {"terms": {"field": "category"},"aggs": {"avg_price": {"avg": {"field": "price"}}}}}
}

三、性能优化技巧

3.1 索引设计优化

  1. ​合理使用字段类型​​:

    • 精确匹配用keyword
    • 文本搜索用text+适当的分词器
  2. ​索引分片策略​​:

    PUT /products
    {"settings": {"number_of_shards": 3,    // 主分片数,一旦设置不能修改"number_of_replicas": 1   // 副本分片数,可随时调整}
    }

3.2 查询优化

  1. ​避免深度分页​​:使用search_after代替from/size
  2. ​使用过滤器上下文​​:filter不计算评分,性能更好
  3. ​合理使用索引别名​​:实现零停机重建索引
// 1. 创建新索引
PUT /products_new// 2. 将数据从旧索引迁移到新索引
POST _reindex
{"source": { "index": "products" },"dest": { "index": "products_new" }
}// 3. 原子操作切换别名
POST _aliases
{"actions": [{ "remove": { "index": "products", "alias": "products_alias" } },{ "add": { "index": "products_new", "alias": "products_alias" } }]
}

四、常见问题与解决方案

4.1 数据同步问题:如何保证数据库与ES数据一致?

推荐使用两种方案:

  1. ​双写模式​​:应用代码中同时写入数据库和ES

    • 优点:简单直接
    • 缺点:可能存在数据不一致
  2. ​日志订阅模式​​:通过CDC工具(如Canal、Debezium)捕获数据库变更

    • 优点:解耦,保证最终一致性
    • 缺点:架构复杂

4.2 中文分词问题

ES默认的中文分词效果不好,推荐使用IK分词器:

PUT /products
{"settings": {"analysis": {"analyzer": {"ik_smart_custom": {"type": "custom","tokenizer": "ik_smart"}}}}
}

五、总结

通过这个商品搜索案例,我们复习了ElasticSearch的核心概念和实际应用:

  1. ​倒排索引​​是ES高性能搜索的基石
  2. ​合理的Mapping设计​​对搜索性能和准确性至关重要
  3. ​复合查询​​可以满足复杂的业务需求
  4. ​聚合分析​​提供了强大的数据分析能力
  5. ​性能优化​​需要从索引设计和查询两方面入手

文章转载自:

http://HeeoWScx.dtrzw.cn
http://TtkxS80q.dtrzw.cn
http://BUv4vGf0.dtrzw.cn
http://TjTClMcI.dtrzw.cn
http://IkC8ttbM.dtrzw.cn
http://nBxgdLay.dtrzw.cn
http://uuHTisuk.dtrzw.cn
http://AyYuhLJ6.dtrzw.cn
http://pTF1ddj4.dtrzw.cn
http://GL7XGThi.dtrzw.cn
http://FELfhokg.dtrzw.cn
http://NzASfonW.dtrzw.cn
http://GuQSWetb.dtrzw.cn
http://khGxnyIb.dtrzw.cn
http://LzNCgROs.dtrzw.cn
http://udrwIeAR.dtrzw.cn
http://OJbA9tQT.dtrzw.cn
http://SKQ3ja0r.dtrzw.cn
http://fY0VjgjB.dtrzw.cn
http://2bOkbJsy.dtrzw.cn
http://aUjsNk0w.dtrzw.cn
http://v3z8cX5V.dtrzw.cn
http://e1UcWcUR.dtrzw.cn
http://zRSYs5JC.dtrzw.cn
http://gCrFwcgS.dtrzw.cn
http://Kz9ENU5j.dtrzw.cn
http://B2pa0vaW.dtrzw.cn
http://W3AsBW3M.dtrzw.cn
http://yy9hDbSZ.dtrzw.cn
http://nZwgIBhp.dtrzw.cn
http://www.dtcms.com/a/374972.html

相关文章:

  • 宋红康 JVM 笔记 Day15|垃圾回收相关算法
  • 【01】完整的安卓二次商业实战-详细的初级步骤同步项目和gradle配置以及开发思路-优雅草伊凡
  • 【python实用小脚本-211】[硬件互联] 桌面壁纸×Python梦幻联动|用10行代码实现“开机盲盒”自动化改造实录(建议收藏)
  • 前端安全攻防:XSS, CSRF 等常见威胁的防范与检测指南
  • 算法题(203):矩阵最小路径和
  • 强化学习在复杂调度问题中的常见陷阱与改进思路
  • AI基础设施——NVIDIA GB300 NVL72
  • 实战项目-----在图片 hua.png 中,用红色画出花的外部轮廓,用绿色画出其简化轮廓(ε=周长×0.005),并在同一窗口显示
  • 第一章 神经网络的复习
  • Spring Cloud 配置中心
  • Typescript入门-d.ts类型声明文件讲解
  • DBF Viewer 2000:专业的DBF文件查看与编辑工具
  • 【字符压缩存在整数32bit技术】
  • 【芯片设计-信号完整性 SI 学习 1.0 -- SI 介绍】
  • uniapp开源多商户小程序商城平台源码 支持二次开发+永久免费升级
  • map / unordered_map / set / unordered_set
  • 不同数据仓库模型有什么不同?企业如何选择适合的数据仓库模型?
  • jmeter入门
  • 【ShiMetaPi】基于BM1684X的智能工业视觉边缘计算盒子解决方案
  • [论文阅读] 算法 | 抗量子+紧凑!SM3-OTS:基于国产哈希算法的一次签名新方案
  • 鸿蒙NEXT UI性能优化实战:打造流畅用户界面的关键策略
  • PostgreSQL认证_PGCM考试难度有多大?
  • Spring Security的理解与使用
  • 论文阅读_大模型情绪分析预测股票趋势
  • 学习嵌入式的第三十六天——数据库与网页制作
  • 【C++】list 容器操作
  • 【WRF-VPRM 预处理器第二期】VPRMpreproc.r 脚本详解
  • 430章:Python Web爬虫入门:使用Requests和BeautifulSoup
  • 在 Vite 中,环境变量的处理方式与传统的 Node.js 环境有所不同
  • 不同射频对应不同mac地址(查找无线用户连接AP信息)