【Agent智能体】33ElasticSearch
章节三十三ElasticSearch1.1 Elasticsearch简介Elasticsearch简称ES一个专门用来搜东西的搜索引擎。它底层基于Lucene一个Java写的搜索库对外提供RESTful接口简单来说就是通过HTTP请求就能完成各种搜索操作。RESTful一种设计风格意思是你可以用普通的网址访问比如 GET、POST 请求来操作数据不需要写复杂的代码。LuceneJava开发的全文搜索库是ES的发动机。ES现在是企业级搜索的首选工具第8版在速度、扩展性和易用性上都有很大提升。注意ES 8最低需要JDK 17。1.2 Elasticsearch的特性实时数据写进去后大概1秒就能搜到几乎感觉不到延迟。分布式、可扩展天生支持多机器集群加机器就能扩容能支持上千台服务器、PB级数据。稳定可靠大厂都在用经历过考验。高可用数据有多份拷贝一台机器挂了不影响使用。Rest API统一的HTTP接口各种编程语言都能调用不用担心API混乱。高性能基于LucenePB级数据也能秒级搜索。多客户端支持Java、Python、Go、PHP等语言都有官方客户端。安全支持提供登录认证、加密通信、权限控制8版本默认开启HTTPS。1.3 Elasticsearch应用场景第一搭建日志系统。用ELK套件Elasticsearch Logstash Kibana收集、存储、可视化日志这是最常见的用法。第二搭建数据分析系统。配合Kibana做数据聚合、统计报表从海量数据里找规律。第三搭建搜索系统。适合做站内搜索比如电商App里的商品搜索、银行App里的服务搜索。第四作为独立数据库。ES本身能存数据、能查数据某些场景下可以直接当数据库用。但要注意它不支持事务写入性能也比MySQL稍弱所以不适合银行转账这类需要强一致性的场景。ES和MySQL的区别第一查询语言不同。MySQL用SQL结构化查询语言ES用基于JSON的DSL查询语法更适合复杂搜索。第二索引结构不同。MySQL主要用B树索引适合有序数据的精确查找。ES用倒排索引适合全文搜索和相似度计算。第三使用场景不同。MySQL适合事务性业务如订单、支付ES适合搜索和分析如日志、全文检索。第四架构不同。ES天生分布式水平扩容方便。MySQL适合结构化数据和中等规模数据。1.4 全文搜索引擎全文搜索就是根据关键词去找内容。传统数据库搜文本很弱因为需要扫描整张表数据量大的时候慢得无法接受。而且每次增删改都要重建索引维护麻烦。全文搜索引擎的工作原理先扫描文章里的每个词给每个词建一个索引表记录这个词在哪些文章里出现过、出现几次、在什么位置。用户搜索时直接查这个索引表瞬间就能找到相关文章。就像查字典的检索字表一样快。1.5 倒排索引正排索引文档 - 关键字。先找到文档再看里面有哪些词。倒排索引关键字 - 文档。先找到词再看哪些文档包含这个词。倒排索引的构建步骤第一步把数据按词条进行分词同时记录每个词出现在哪个文档的哪个位置。第二步把相同的词条合并到一起。第三步对词条排序方便后续快速查找。搜索过程第一步把用户输入的搜索词进行分词。第二步拿分好的词去倒排索引里查找到包含这些词的文档ID。第三步根据文档ID取出真正的文档数据返回给用户。3 Elasticsearch核心概念3.1 ES对照数据库可以把ES理解为一种特殊的数据库但术语不一样索引Index类似MySQL的表存着一类相似的数据。文档Document类似MySQL的一行记录ES里用JSON格式表示。字段Field类似MySQL的列是文档的一个属性。映射Mapping类似MySQL的建表语句定义字段的类型、是否分词等规则。3.2 索引Index索引就是一类相似文档的集合。比如你可以有一个客户索引、一个商品索引、一个订单索引。索引名必须全小写。ES里能搜索的数据必须建索引就像字典前面的目录目的是提高查询速度。ES索引设计的精髓一切都是为了提高搜索性能。3.3 类型Type类型索引内部的逻辑分类。但ES从6版本开始逐步弱化type7版本后默认只有一个类型_doc。为什么要弱化type第一性能考虑。ES的核心优势是全文检索依赖倒排索引而倒排索引是基于索引而非type的多个type反而增加复杂度。第二数据结构简化。同一个索引里不同type的同名字段底层用的是同一个存储容易导致数据稀疏影响压缩效率。第三避免误解。很多人把索引类比成数据库、type类比成表但两者其实不一样这种错误类比容易用错。第四逐步过渡。前期很多项目用了多type所以ES采取渐进式废除给开发者时间调整。3.4 文档Document文档ES里存数据的最小单位就是一条记录。用JSON格式表示一个索引里可以存任意多条文档。3.5 字段Field字段文档的属性相当于表的列。比如一个商品文档可以有名称、“价格”、类别等字段。3.6 映射Mapping映射定义字段的规则比如字段类型字符串、数字、日期、是否建立索引、用什么分词器等。合理设置映射能大幅提升性能。4 Elasticsearch基础功能参考文档https://www.elastic.co/guide/en/elasticsearch/reference/8.5/elasticsearch-intro.html操作演示在Kibana里进行。4.1 分词器分词器决定一段话怎么被拆成一个个词。比如我是中国人不同的分词器拆法不一样。ES自带的Standard分词器默认分词器对中文是单字切分拆成我、“是”、“中”、“国”、“人”。IK分词器第三方中文分词器能按词语级别拆分拆成我、“是”、“中国人或中国”、“人”。# 功能说明测试分词效果# POST _analyze 调用分析接口# 指定analyzer和text查看分词结果4.2 索引操作# 功能说明索引类似表的增删查操作# PUT /索引名 创建索引# GET /_cat/indices?v 查看所有索引# GET /索引名 查看单个索引详情# DELETE /索引名 删除索引4.3 文档操作文档ES里搜索数据的最小单位格式灵活不需要预先定义字段。# 功能说明文档类似行记录的增删改查# PUT /索引名/_doc/ID 创建或更新文档需指定ID# GET /索引名/_doc/ID 根据ID查文档# GET /索引名/_search 查询所有文档# POST /索引名/_update/ID 局部更新文档只能改部分字段# DELETE /索引名/_doc/ID 删除文档注意局部更新只能用POST方式。4.4 映射Mapping动态映射写文档时ES自动识别字段类型不用提前建表。比如写个字符串自动当成text类型写个整数自动当成long类型。静态映射提前手动定义好每个字段的类型、分词器等规则像MySQL建表一样。适合对性能有要求的场景。常见字段类型text长文本支持分词但不能排序和聚合。keyword不分词适合精确匹配、排序、聚合。long/integer/float/double数值型。date日期型。boolean布尔型。# 功能说明创建索引时同时指定映射规则# PUT /索引名 {# mappings: {# properties: {# title: {type: text, analyzer: ik_max_word},# price: {type: integer}# }# }# }5 DSL高级查询5.1 DSL概述DSLDomain Specific LanguageES专用的查询语言用JSON格式写查询条件。可以理解为ES的SQL。DSL查询分为两类叶查询在特定字段里查特定值比如match、term、range可以单独使用。复合查询组合多个查询条件比如must必须满足相当于AND、should满足其一即可相当于OR、must_not必须不满足相当于NOT、filter过滤不计算得分。5.2 DSL查询类型match_all查询所有文档不做任何过滤。match全文搜索会对搜索词进行分析后再匹配有模糊匹配能力。比如搜华为智能手机可能匹配到华为手机。multi_match在多个字段里同时搜索。比如同时在标题和分类里搜关键词。term精确匹配不会对搜索词分词。比如搜华为手机就必须完全匹配这四个字不能是华为或手机。terms匹配多个值中的任意一个。比如搜华为手机或vivo手机。bool组合查询把多个条件组合起来。must所有条件都必须满足AND关系。should满足任意一个条件即可OR关系。must_not必须不满足所有条件NOT关系。filter效果和must一样但不计算相关度得分速度更快。# 功能说明DSL查询示例# match_all 查所有# match 全文模糊匹配# multi_match 多字段搜索# term/terms 精确匹配# bool must/should/must_not/filter 组合条件查询5.3 排序# 功能说明对搜索结果排序# 可以按字段排序如价格升序asc、降序desc# 也可以按相关度得分_score排序