ES分词搜索

article/2025/7/26 9:44:33

ES的使用

    • 前言
      • 作者使用的版本
      • 作者需求
    • 简介
      • ES简略介绍
      • ik分词器简介
    • 使用
      • es的直接简单使用
        • es的查询
      • es在java中使用
      • 备注说明

前言

作者使用的版本

  • es: 7.17.27
  • spring-boot-starter-data-elasticsearch: 7.14.2

作者需求

作者接到一个业务需求,我们系统有份数据被用来查询,进行搜索改造。我们的数据是可以分为两层,第一层是物品,物品含有物品名和物品别名。第二层是规格型号,一个物品可以配置多个规格型号,同一物品不同规格型号有不同的价格。
原先的搜索只支持对物品名或别名的模糊搜索。将带出该物品下所有的规格列表被用来选择。比如说原来数据库里有个物品叫做 蒙古大马,如果使用蒙古的大马进行搜索时搜索不到的,需要对这种搜索进行支持。
于是,作者选用了es作为文本搜索。作者只达到了可用的效果,并没有深究es的文档。底部会放置文档链接。
如上所述,本文并不对es做详细介绍。在上面说明中,作者已经碰到了问题,而es可以解决这个问题,所以本文只大概讲述es为什么能够解决我的问题以及我如何使用es解决问题

简介

ES简略介绍

es为什么能够解决我的问题,我想要的搜索场景是,可以从用户输入的文本串中提取出有用的匹配信息,然后到我的数据库中对待匹配的信息进行匹配。命中即认为该数据是用户需要的,用户输入文本可能与数据库中的某段信息的文字部分是完全一致的,但是文字顺序是被打乱的。mysql数据库支持like,所以可以将用户输入文字串分割成每个字,然后用or去拼接查询。这种查询效率和使用方式可想而知有多么恐怖。但是es不需要这么麻烦的使用姿势,es支持match,可以对文本进行匹配搜索。为什么MySQL这么麻烦,而es看起来很方便呢?因为他们主要的应用场景就不同,所以底层的数据结构就不同。首先看看他们对数据的索引方式:
MySQL的索引方式很简单,一条记录留存,如果指定了需要索引某个字段,就会将这个字段的对应记录的ID拿出来,存储到B+树中,二分搜索可以对有序数据进行快速查找,但是如果使用like '%x%';可以看到无法判断要匹配文本的首字母了,也就是无法使用索引了,这样数据量一旦上来,查询效率会飞快下降。
es的索引方式中文一直叫做倒排索引,什么叫倒排索引,在mysql中,索引的是这个字段的全文本,然后用全文本去匹配我们的输入,如果匹配不到就错了,换个数据继续匹配。这个思路就是,我们需要所有数据的全文本,然后挨个匹配。可现在的场景是需要这么做,你只需要给我输入的文本内有效部分的有关数据即可。所以我们首先需要考虑将输入信息进行分割提取。然后用提取出来的每部分数据参与匹配。那有个想法,如果我存的数据,也按照这种分割-提取来提前建立一份索引呢?那就可以用提取到的部分输入直接去匹配数据库里提前存储好的数据的索引。匹配到一个部分即认为命中,匹配到多个部分认为相关度更高,最终得分也就越高。这种将文档的文本打散进行索引再反过来查询文档的,被称作倒排索引

ik分词器简介

既然有个数据库可以支持倒排索引,那么接下来就看看怎么对文本分词,首先一个问题是为什么要分词,如果不分词,我输入一段话,每个字都是一个token。那如果我认为有些字按照一定的顺序组合起来有固定的含义,他们就成了词,词就意味着通用,我们在存储和使用时都会按照这个顺序。即他们也可以做token。这样一份文档的token数量就会减少,这样可以显著提升查询的效率。
但是这也有个问题,比如上文的内蒙大马。如果我用了分词器,ik的通用词库里有蒙古、大马,我现在用去搜索,命中结果集为空,因为这段文本被索引为蒙古大马,你用是匹配不到大马这个索引的。字是默认组词使用的,如果有单字也是可以用使用的特殊情况,可以在词典里添加这个单字,需要注意词的顺序,最短的词放在上面,否则由于分词器是不贪心的,已经匹配了一个比较好的索引,就不去再考虑生成一个差的索引了。词典添加后还要注意不要使用ik_smart类型的分析器,下文会有说明。如果你认为你的场景每个字都需要考虑,那就简单了,不要分词,以改兼赈、两难自解;

es本身不支持中文分词,ik分词器可以支持中文的分词,所以需要ik分词器。ik分词有两种type:
ik_smart:对文本进行粗粒度分词,比如蓝瘦香菇这个词,我如果词典里有蓝瘦香菇蓝瘦香菇。他的分词结果蓝瘦香菇;显然,他的索引数量会更少,也会丢掉更多数据的查询。
在这里插入图片描述

ik_max_word,进行最粗粒度的分词,会列举所有的可能(但不包括已经被组词的字,所以单字的特殊情况可以将它作为词来解决)。
在这里插入图片描述
每次更新词库都需要重启,这太费劲了,还好ik支持热更新词库。只需要在配置文件配置remote_ext_dict即可。但是,更新词典后只对之后的新数据有效,旧有数据需要重建索引

使用

es的直接简单使用

  • 创建索引
PUT /index_name
{"mappings": {"properties": {"ref_id": { "type": "long" },"ref_type": { "type": "integer" },"goods_name": { "type": "text","analyzer":"my_ik_analyzer","search_analyzer":"ik_max_word"},"param_value": { "type": "text","analyzer":"my_ik_analyzer","search_analyzer":"ik_max_word"}}}
}
  • 删除索引
DELETE /index_name
  • 新增或更新文档
POST /index_name/_doc/doc_id # 最后一位参数可以指定生成的文档ID
{
"ref_id": 1,
"ref_type":1,
"goods_name": "狗;犬;野狗;导盲犬",
"param_value": "中华田园犬;美国狗;吃狗粮;奥利给"
}
  • 分析测试
POST /index_name/_analyze?pretty
{
"analyzer": "ik_max_word", 
"text":"内蒙大马"
}
  • 查询
POST /bws_price_library/_search?pretty
{"query":
{"bool":{"must": [{  "multi_match": {"query":"大马","fields":["goods_name^2","param_value"]  #字段名后面的^n可以指定得分权重。}},{"term":{"ref_type":"101"}}]}
}}
es的查询

es的查询很负责,所以能覆盖非常多的场景。作者上面涉及 准确查询term、匹配查询match,多字段匹配查询multi_match、布尔嵌套查询bool,只做了简单的示例,很容易触类旁通。具体的使用方式作者有时间会慢慢补充。

es在java中使用

  • 保存
XXXXIndex index = new XXXXIndex();index.setId(BwsPriceConstant.SPECS_REF_TYPE_PART+"_"+id);index.setRefId(id);index.setRefType(BwsPriceConstant.SPECS_FEE_TYPE_PART);index.setGoodsName("name");index.setParamValue("value");IndexCoordinates indexCoordinates = elasticsearchRestTemplate.getIndexCoordinatesFor(XXXXIndex.class);elasticsearchRestTemplate.save(index,indexCoordinates);
  • 删除
elasticsearchRestTemplate.delete(id, XXXXIndex.class);
  • 更新
            IndexCoordinates indexCoordinates = elasticsearchRestTemplate.getIndexCoordinatesFor(XXXXIndex.class);Document document = Document.create();document.setId(index.getId());document.putIfAbsent("ref_id",index.getRefId());document.putIfAbsent("ref_type",index.getRefType());document.putIfAbsent("goods_name",index.getGoodsName());document.putIfAbsent("param_value",index.getParamValue());elasticsearchRestTemplate.update(UpdateQuery.builder(index.getId()).withDocument(document).build(),indexCoordinates);
  • 查询
       Pageable pageable = PageRequest.of(reqVo.getCurrentPage()-1, reqVo.getPageSize());Map<String, Float> fields = new HashMap<>();fields.put("goods_name",3.0f);fields.put("param_value",1.0f);// 查询实体使用构造器模式,multiMatchQuery.fields方法可以指定查询权重,查看构造方法可以看到默认是都给了1的权重。这个权重也可以在构建索引的时候指定,不过查询时指定的话会更灵活一些NativeSearchQuery build = new NativeSearchQueryBuilder().withPageable(pageable).withQuery(new BoolQueryBuilder().must(new TermQueryBuilder("ref_type", reqVo.getFeeType())).must(QueryBuilders.multiMatchQuery(reqVo.getName(), "goods_name", "param_value").fields(fields))).build();SearchHits<XXXXIndex> search = elasticsearchRestTemplate.search(build, XXXXIndex.class);List<SearchHit<XXXXIndex>> searchHits = search.getSearchHits();// SearchHit中的Content就是指定的类型对象

备注说明

在使用时建议做好数据的手动同步,以防万一


http://www.hkcw.cn/article/oDHljSbfkP.shtml

相关文章

Drawio编辑器二次开发

‌ Drawio &#xff08;现更名为 Diagrams.net &#xff09;‌是一款完全免费的在线图表绘制工具&#xff0c;由 JGraph公司 开发。它支持创建多种类型的图表&#xff0c;包括流程图、组织结构图、UML图、网络拓扑图、思维导图等&#xff0c;适用于商务演示、软件设计等多种场景…

破解高原运维难题:分布式光伏智能监控系统的应用研究

安科瑞刘鸿鹏 摘要 高原地区光照资源丰富&#xff0c;具有发展分布式光伏发电的巨大潜力。然而&#xff0c;该地区复杂的气候环境、地形地貌和运维条件对光伏电站的运行与维护带来严峻挑战。本文结合Acrel1000DP分布式光伏监控系统的技术特点和典型应用案例&#xff0c;探讨其…

Golang|分布式搜索引擎中所使用到的设计模式

迭代器模式 定义&#xff1a;在遍历接口时&#xff0c;提供统一的方法函数供调用&#xff0c;保持一致性。核心思想&#xff1a;与大众习惯保持一致&#xff0c;方便第三方实现容器类时保持一致。常见方法&#xff1a;如next()方法&#xff0c;适用于所有集合类&#xff0c;简化…

招工招聘系统开发——适配多元场景,满足企业多样化招聘需求

不同的企业有不同的招聘需求&#xff0c;不同的岗位也有不同的招聘特点。我们的招工招聘系统开发&#xff0c;充分考虑了企业的多样化需求&#xff0c;适配多元场景&#xff0c;为企业提供全方位的招聘解决方案。 对于大型企业来说&#xff0c;招聘规模大、岗位种类多、招聘流…

优化版本,增加3D 视觉 查看前面的记录

上图先 运来的超出发表上限&#xff0c;重新发。。。 #11:06:57Current_POS_is: X:77Y:471Z:0U:-2 C:\Log\V55.txt import time import tkinter as tk from tkinter import messagebox from PIL import Image, ImageTk import socket import threading from date…

《TCP/IP 详解 卷1:协议》第2章:Internet 地址结构

基本的IP地址结构 分类寻址 早期Internet采用分类地址&#xff08;Classful Addressing&#xff09;&#xff0c;将IPv4地址划分为五类&#xff1a; A类和B类网络号通常浪费太多主机号&#xff0c;而C类网络号不能为很多站点提供足够的主机号。 子网寻址 子网&#xff08;Su…

JNI开发流程

一. 引言 最近在做一个自己的项目&#xff0c;就是基于FastDDS封装一套JAVA库&#xff0c;让android和java应用可以使用dds的功能。 由于FastDDS是使用C编写的开源库&#xff0c;因此java的类库想要调用FastDDS的接口&#xff0c;需要额外编写一个JNI层的动态库对FastDDS的接口…

powershell 中 invoke-expression 报错解决

打开powershell就出现这个报错&#xff1a; 网上搜了也没有很好的解决办法&#xff0c;抱着一点点期待&#xff0c;问了豆包 根据豆包的指示&#xff0c;在终端执行以下 几个命令&#xff0c;报错解决了&#xff08;开心万岁&#xff09; # 移除多余的引号和空路径 $pathArra…

交错推理强化学习方法提升医疗大语言模型推理能力的深度分析

核心概念解析 交错推理:灵活多变的思考方式 交错推理(Interleaved Reasoning)是一种在解决复杂问题时,不严格遵循单一、线性推理路径,而是交替、灵活应用多种推理策略的方法。这种思维方式与人类专家在处理复杂医疗问题时的思考模式更为接近,表现为一种动态、适应性强的…

【下载ECharts最简单的方法】

最简单下载ECharts的方法 对于简单项目&#xff0c;我们需要的echarts文件是echarts.min.js&#xff0c;以下是下载ECharts的最简单方法&#xff1a; 方法一&#xff1a;直接下载&#xff08;推荐初学者&#xff09; 访问ECharts官网&#xff1a;https://echarts.apache.org…

西藏建筑安全员 B 证考试中常见的 单选题及解析

西藏建筑安全员 B 证考试中常见单选题及解析&#xff0c;涵盖安全生产管理、法律法规、安全技术等核心考点&#xff0c;结合西藏地区建筑施工特点整理&#xff0c;帮助理解考试重点&#xff1a; 一、安全生产管理基础 1. 安全管理原则与制度 1、建筑施工安全管理的方针是&am…

案例分享--血管支架的径向力分布评估--DIC数字图像相关技术用于生物医学-高置信度DIC测量

医疗设备制造商有责任创造和确保高效且安全的产品&#xff0c;以守护人类的健康。EchoBio LLC公司的Kenneth Perry博士是植入式医疗设备实验验证行业的领导者和专家。Perry博士的一项研究任务是评估用于疏通血管阻塞的编织自膨胀支架的径向力分布。Perry博士特别需要关注径向力…

[Javascript进阶]JSON.stringify与JSON.parse详解

JSON.stringfy JSON.stringify 的核心作用是&#xff1a; &#x1f449; 将 JS 的对象、数组、基本类型转换为合法的 JSON 字符串。 手撕实现时&#xff0c;要考虑以下几个方面&#xff1a; 基本类型处理&#xff1a; string → 加上双引号&#xff0c;注意转义&#xff1b;nu…

VirtualBox给Rock Linux9.x配置网络

写这篇文章之前&#xff0c;先说明一下&#xff0c;我参考的是我之前写的《VirtualBox Linux网络配置》 我从CentOS7转到了Rock9&#xff0c;和配置Centos7一样&#xff0c;主流程没有变化&#xff0c;变化的是Rock9.x中的配置文件和使用的命令。 我再说一次&#xff0c;因为主…

逆向分析基础总结

一、了解计算机部件 CPU&#xff1a; 中央处理器。有三个重要的部件&#xff1a; 逻辑部件&#xff1a;负责算数运算&#xff0c;包括定点运算、浮点运算等。 寄存器部件&#xff1a;负责临时数据存储&#xff0c;一个CPU包含多个寄存器。 控制部件&#xff1a;负责发出指令所…

企业信息化集成方案:聚水潭·奇门数据对接金蝶云星空

聚水潭奇门数据集成到金蝶云星空&#xff1a;销售退货单更新方案 在企业信息化管理中&#xff0c;数据的高效流动和准确对接是实现业务流程自动化的关键。本文将分享一个实际案例&#xff0c;展示如何通过轻易云数据集成平台&#xff0c;将聚水潭奇门系统中的销售退货数据无缝…

多功能文档处理工具推荐

软件介绍 今天为大家介绍一款功能强大的文档编辑工具坤Tools&#xff0c;这是一款在吾爱论坛广受好评的办公软件。 软件背景 坤Tools是由吾爱论坛用户分享的软件&#xff0c;在论坛软件榜单上长期位居前列&#xff0c;获得了用户的一致好评。 软件性质 这是一款完全离线、…

软考-系统架构设计师-第十八章 面向服务架构设计理论与实践

面向服务架构设计理论与实践 18.1 SOA 的相关概念18.2 SOA 的发展历史18.3 SOA 的参考架构18.4 SOA 主要协议和规范18.5 SOA 设计的标准要求18.6 SOA 的作用与设计原则18.7 SOA 的设计模式18.8 构建 SOA 架构时应该注意的问题18.9 SOA 实施的过程 18.1 SOA 的相关概念 &#x…

AI书签管理工具开发全记录(五):后端服务搭建与API实现

文章目录 AI书签管理工具开发全记录&#xff08;四&#xff09;&#xff1a;后端服务搭建与API实现前言 &#x1f4dd;1. 后端框架选型 &#x1f6e0;️2. 项目结构优化 &#x1f4c1;3. API路由设计 &#x1f9ed;分类管理书签管理 4. 数据模型定义 &#x1f4be;分类模型&…

CentOS-stream-9 Zabbix的安装与配置

一、Web环境搭建部署Zabbix时&#xff0c;选择合适的MariaDB、PHP和Nginx版本非常重要&#xff0c;以确保兼容性和最佳性能。以下是建议版本&#xff1a;Zabbix 6.4 MariaDB&#xff1a;官方文档推荐使用MariaDB 10.3或更高版本。对于CentOS Stream 9&#xff0c;建议使用Maria…