Spring Boot + Elasticsearch实现大批量数据集下中文的精确匹配-案例剖析

2023-11-17

缘由

数据存储在MYSQ库中,数据基本维持不变,但数据量又较大(几千万)放在MYSQL中查询效率上较慢,寻求一种简单有效的方式提高查询效率,MYSQL并不擅长大规模数据量下的数据查询。

技术方案

考虑后期同样会使用到es,此次直接结合spring-boot框架形成一个独立服务,并不涉及UI展现内容,(ES版本2.4.5,5.0+版本的话就不能再使用spring data elasticsearch)技术组合如下:

Spring Boot+ Spring-data-elasticsearch + Elasticsearch

结合elasticsearch-jdbc插件,全量将数据一次性导入es中,后期不涉及数据变更。

es安装

测试期间单机安装,官网下载对应版本,由于笔者工作环境基于JDK7,所以下载5.0以下版本,5.0+均依赖Java8,同时使用到elasticsearch-jdbc插件,一并下载安装完成。

走过的大弯路

直接使用elasticsearch-jdbc工具,编写脚本文件,抽取数据到es中,脚本样例如下:

 
  1. #!/bin/sh

  2.  

  3. DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

  4. bin=${DIR}/../bin

  5. lib=${DIR}/../lib

  6.  

  7. echo '

  8. {

  9.    "type": "jdbc",

  10.    "jdbc": {

  11.        "elasticsearch.autodiscover": true,

  12.        "url": "jdbc:mysql://192.168.1.3:3306/test",

  13.        "user": "root",

  14.        "password": "root",

  15.        "sql": "SELECT * from tb_name1",

  16.        "elasticsearch": {

  17.            "host": "192.168.1.1",

  18.            "port": 9300

  19.        },

  20.        "index": "my-index",

  21.        "type": "my-type"

  22.    }

  23. }

  24. ' | java \

  25.    -cp "${lib}/*" \

  26.    -Dlog4j.configurationFile=${bin}/log4j2.xml \

  27.    org.xbib.tools.Runner \

  28.    org.xbib.tools.JDBCImporter

数据导入成功后,可使用head插件直接查看到。使用基本查询测试,查询条件是name=测试&num=100,使用精确匹配term语句,查询数据未果,实际使用num=100独立查询时,有相关数据。

问题跟踪解决

导致此现象的原因在于中文分词的问题,使用elasticsearch-jdbc脚本中并未处理列的mapping类型。(中间做过一次尝试,在脚本中定义对应的type_mapping,但并未成功,有兴趣的朋友可再做尝试)。

注:es与ik分词插件结合,版本匹配需要特别关注,但本案例并不涉及

结合此案例,查询时并不需要分词,而是精确匹配,但es默认情况下是指定string类型的分词,所以在index创建之前我们需要手动指定相关列不需要分词:not_analyzed,形如:

 
  1. CURL -XPOST http://192.168.1.105:9200/my-index -d {

  2.  

  3.    {

  4.    "mappings": {

  5.        "my-type": {

  6.            "properties": {

  7.                "name": {

  8.                    "type": "string",

  9.                    "index": "not_analyzed"

  10.                },

  11.                "num": {

  12.                    "type": "string",

  13.                    "index": "not_analyzed"

  14.                }

  15.            }

  16.        }

  17.    }

  18. }

创建索引成功后,再使用elasticsearch-jdbc的脚本导入数据,相关数据列不会再使用分词分析,再使用term组合精确查询时,就可以查询相关数据来。

SpringBoot应用

pom.xml关键配置

 
  1. <dependency>

  2.    <groupId>org.springframework.boot</groupId>

  3.    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>

  4. </dependency>

  5. <dependency>

  6.    <groupId>org.springframework.boot</groupId>

  7.    <artifactId>spring-boot-starter-web</artifactId>

  8.    <exclusions>

  9.        <exclusion>

  10.            <artifactId>log4j-over-slf4j</artifactId>

  11.            <groupId>org.slf4j</groupId>

  12.        </exclusion>

  13.    </exclusions>

  14. </dependency>

  15. <dependency>

  16.    <groupId>org.springframework.boot</groupId>

  17.    <artifactId>spring-boot-starter</artifactId>

  18.    <exclusions>

  19.        <exclusion>

  20.            <groupId>org.springframework.boot</groupId>

  21.            <artifactId>spring-boot-starter-logging</artifactId>

  22.        </exclusion>

  23.    </exclusions>

  24. </dependency>

  25. <dependency>

  26.    <groupId>org.springframework.boot</groupId>

  27.    <artifactId>spring-boot-starter-test</artifactId>

  28.    <scope>test</scope>

  29. </dependency>

  30. <dependency>

  31.    <groupId>org.springframework.boot</groupId>

  32.    <artifactId>spring-boot-starter-log4j</artifactId>

  33.    <version>1.3.1.RELEASE</version>

  34. </dependency>

与elasticsearch交互实体

 
  1. @Data

  2. @Document(indexName = "my-index", type = "my-type", shards = 5, replicas = 1, indexStoreType = "fs", refreshInterval = "-1")

  3. public class DataBean {

  4.  

  5.    /**

  6.     * code:名称

  7.     *

  8.     * @since JDK 1.6

  9.     */

  10.    public String name;

  11.  

  12.    /**

  13.     * msg:编号

  14.     *

  15.     * @since JDK 1.6

  16.     */

  17.    public String num;

  18.  

  19. }

与es交互接口类,返回数据的唯一_id值,若查得数据表示命中数据,若为空并未数据不存在

 
  1. public interface DataBeanRepository extends ElasticsearchRepository<DataBean, Long> {

  2.    //案例中并未使用,但可以用

  3.    public List<BlackGreyData> findByNameAndNum(String name, String num);

  4. }

下面是业务处理层,采用BoolQueryBuilder构建查询条件,也即可基于DSL模块查询数据,还可以采用Criteria查询。

 
  1. @Autowired

  2.    DataBeanRepository repository;

  3.  

  4.    @Override

  5.    public List<DataBean> query(String name, String num, String type) {

  6.        //采用过滤器的形式,提高查询效率

  7.        BoolQueryBuilder builder = QueryBuilders.boolQuery();

  8.        builder.must(QueryBuilders.termQuery("name", name)).must(QueryBuilders.termQuery("num", num));

  9.        Iterable<DataBean> lists = repository.search(builder);

  10.  

  11.        List<DataBean> datas = new ArrayList<>();

  12.        for (DataBean dataBean : lists) {

  13.            datas.add(dataBean);

  14.            logger.info("---------------------->>>Request result = 【" + dataBean + "】");

  15.        }

  16.        return datas;

  17.    }

其它再编写对应的请求响应逻辑,即可完成简单服务的完成。

测试结果

GPS数据量5000W+,精确匹配查询出来50条数据,耗时700ms左右,结果查询缓存机制,基本可以稳定在300ms左右。这也是在单节点,未作任何优化的情况的结果。

源码地址

https://github.com/backkoms/spring-boot-elasticsearch

欢迎加入我的星球

扩展阅读:

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring Boot + Elasticsearch实现大批量数据集下中文的精确匹配-案例剖析 的相关文章

随机推荐

  • tensorflow安装教程(一般使用国内的清华源进行安装)

    注 安装tensorflow numpy这些源 记得用国内的清华镜像源 国外的源由于网络延迟无法安装 1 国内安装tensorflow的命令 pip install index url https pypi douban com simpl
  • 法拉克机器人自动怎么调_发那科机器人的简单设置你知道吗

    发那科机器人使用后台逻辑时 可以在后台执行只包含对应后台逻辑指令的TP程序 程序从 初到 后被反复执行 该执行不受急停 暂停 报警的影响 设定后台逻辑的步骤非常简单 1 按下MENU键 2 选择SETUP 3 选择BG LOGIC 进入如下
  • 洛谷P5731——蛇形方阵(c++)

    题目描述 给出一个不大于 9 的正整数 n 输出 n n 的蛇形方阵 从左上角填上 1 开始 顺时针方向依次填入数字 如同样例所示 注意每个数字有都会占用 3 个字符 前面使用空格补齐 输入格式 输入一个正整数 n 含义如题所述 输出格式
  • Qt 设置窗口的背景图片

    Qt 设置窗口的背景图片 一 给Qt窗口设置背景图片 mainwindow cpp 设置背景图片 path 图片路径 void MainWindow setBackgroundImage QString path QPixmap pixma
  • 零基础学习Vue: 第38课 Vue单页面使用router-link实现页面跳转小案例:

    零基础学习Vue 第38课 Vue单页面使用router link实现页面跳转小案例 实现效果如下 以下是所有代码
  • Ubuntu操作遇到的报错解决方法汇总(持续更新)

    1 在anaconda中创建了虚拟环境并安装了pytorch 但是编译过程中仍然报没有torch的错误 CMake Error at crawler crane crane tutorials CMakeLists txt 23 find
  • Form表单提交数据的几种方式

    1 submit提交 在form标签中添加Action 提交的地址 和method post 且有一个submit按钮
  • conda安装OpenCV

    安装参考 错误方法conda install channel https conda anaconda org menpo opencv3 C Users 15761 gt conda install channel https conda
  • Cplex求解QCP非线性规划

    import ilog concert import ilog cplex public class QCPex1 public static void main String args try IloCplex cplex new Ilo
  • Environment variable CLASSPATH not set!

    hdfs 问题 Environment variable CLASSPATH not set getJNIEnv getGlobalJNIEnv failed WARNING Logging before InitGoogleLogging
  • is not eligible for getting processed by all BeanPostProcessors

    BeanPostProcessor是控制Bean初始化开始和初始化结束的接口 换句话说实现BeanPostProcessor的bean会在其他bean初始化之前完成 BeanPostProcessor会通过接口方法检查其他类型的Bean并做
  • Visio 2013绘制时序图

    为什么要绘制时序图 我们编码的时候 知道有的用例的业务逻辑按照比较确定的时间先后顺序进行展开 这时候 我们就需要知道我们设计的系统中的不同类之间传递消息 可以认为是不同对象函数间的调用 要按照怎么样的顺序 传递什么消息 返回什么消息 这时候
  • Altium designer 原理图转换为pcb时出现的 unknown pin 和 failed to add class member

    网上有很多方法 大部分都是让直接新建一个pcb文件 这显然太不现实了 上述错误可以看出 unknown pin 的错误是在add pin to net的时候发生的 failed to add class member 的错误实在add to
  • 开源库TinyXML2简介及使用

    TinyXML2是一个开源 简单 小巧 高效的C XML解析器 它只有一个 h文件和一个 cpp文件组成 可以轻松集成到其它程序中 它解析XML文档并从中构建可以读取 修改和保存的文档对象模型 Document Object Model D
  • matplotlib绘制折线图

    matplotlib绘制折线图 这阳春三月的邵大白在家过的什么日子 幽栖地僻经过少 花径不曾缘客扫 开个逗b号纪念下这段闭关的时光 万一他以后就变成一个数据分析的大v号了来 好了邵大白课堂开课了 折线图绘制 咱先画个图 载慢悠的加东西 导包
  • Java基础(十三):枚举、注解

    文章目录 一 设置 author标签 二 枚举 enum 一 枚举的两种实现方式 二 enum常用方法 三 注解 一 设置 author标签 设置 author等标签 以后每次创建一个类 自动带着作者信息 二 枚举 enum 枚举表示一组常
  • git提交规范

    1 新功能用add 2 改bug用fix 3 如果使用禅道或者jira 在add或fix后面加上 编号如 add 3563 gt 1 指标名称修改
  • Android Studio解决gradle时下载资源过慢问题

    替换镜像下载方式 打开Android Studio项目中的build gradle文件 找到以下位置 修改jcenter地址为 https maven aliyun com repository jcenter 示例 buildscript
  • 前端实战:小实例5——锚点导航

    前言 锚点定位用于网站某一模块的定位 让用户能够通过锚点直接跳到相应模块 从而实现页面内跳转 常在网页内容较长时使用 多个锚点显示可用一个无序列表显示 利用 ul 和 li 标签 在 li 标签中使用 a 标签实现锚点 对应标签用法可查看
  • Spring Boot + Elasticsearch实现大批量数据集下中文的精确匹配-案例剖析

    缘由 数据存储在MYSQ库中 数据基本维持不变 但数据量又较大 几千万 放在MYSQL中查询效率上较慢 寻求一种简单有效的方式提高查询效率 MYSQL并不擅长大规模数据量下的数据查询 技术方案 考虑后期同样会使用到es 此次直接结合spri