【Java项目】不使用ES实现关键词搜索问题

news2024/9/19 18:24:36

文章目录

  • 需求
  • 解决思路
    • 基本设计
    • 查询流程
    • 插入流程
    • 修改流程
    • 删除流程
  • 优化思路
  • 总结

需求

ok,这个需求是我提的,然后我问了我的一位杭州的朋友,然后我们最后一起敲定这个方法。

我的项目有一个根据关键字进行商品名称的搜索功能,用户输入部分关键字之后,那么就需要查询出这个关键字对应的所有商品。假设我现在有1000w行记录,并且不能使用ES做倒排索引解决这个问题。
那么你会如何解决这个问题?
我们先分析,如果我们使用数据库提供的 % 这种模糊匹配机制,首先我们的索引会失效,并且这基本意味着会走全表扫描,对于1000w行的记录如果我们走全表扫描,那么效率可想而知。
并且如果使用分库分表技术,那么维护的难度也大了,不论是业务代码还是数据库都得跟着修改,非常麻烦,那么如何解决这个问题?

解决思路

基本设计

大概流程如下:
我们可以自己实现一个倒排索引的算法,用户创建商品之后,将商品名称进行细粒度的分词,比如输入 “Java技术指导”,那么分词为“Java”,“技术”,“指导”。粒度越细越好。
可以看到此时我们得到的是一个数组,对吧。
然后我们创建两张表,一张表是商品表,存储商品的完整信息。
另一张表是倒排索引表,里面是什么内容?
包括id,word,goods_ids
这里的word就是我们的分词数据,goods_ids也就是我们这个关键字下面对应的所有商品id。
上面我们对一个字符串进行分词后得到的,其实是一个数组对吧,那么我们此时就可以向数据库中插入这三行的数据了,大概格式如下。
在这里插入图片描述
然后我们得到goods_ids是一个集合,我们在使用这个集合去商品表中查询出所有在这个集合中的记录即可。

查询流程

那么我现在大概简述一下一个数据的查询流程:
我们查询一个商品,通过关键字的方式,经过倒排索引的算法得到word值,去数据库中查询是否有这个word值,如果有,那么直接查询出来这个关键字对应的goods_ids这一段字符串,我们对字符串进行处理得到字符串包含的所有id,然后用这些id去商品表查询数据即可。

ok,那么如果有插入和修改,删除等操作怎么办呢?

插入流程

先说插入流程,一样的,当我们要插入一个数据的时候,我们先得到这个商品对应的word,也就是我们取出商品的name商品名称字段,然后对这个name字段进行分词算法,得到细粒度的分词。之后,我们我们将这个记录插入到商品表中,得到插入的id之后,返回id成功后,我们在将分词得到的数组,配合上我们得到的商品id,循环的去插入到这个分词表中,如果分词表中出现了重复的word,那么我们做的是取出goods_ids这个字段,然后再字段尾巴上补上这个id,而如果不存在这个字段,则新建一行记录,word为当前分词,goods_ids直接为刚才返回的id。

修改流程

修改流程其实已经和上面的流程差不多了,依旧是经过分词,然后去精确判断分词对应的行,然后修改对应的ids字段即可。

删除流程

删除流程也差不多,只不过我们如何删除对应的goods_ids中的哪一个id呢?
我们首先取出goods_ids这个字段值,然后通过 “ ,”分隔符得到每一个id,然后我们删除指定的id即可,当然,为了加快速度,我们的商品表中的id是自增的,所以这样子就能尽可能快的删除指定数据了。

优化思路

其实,顺着上面的思路,我忽然想到。其实我们的数据库其实作用就是为了保存一个分词,然后分词后面对应的是一堆的id,这些id是字符串,也就是我们取出来之后还得先经过处理才能得到真正可用的id。
我想的是,上面的结构其实很简单,就是一个 word—goods_ids的结构,这种结构用Redis肯定可以呀对吧。
但是如果你直接K-V结构或者hash,那么结构其实相当于就是把磁盘空间变成了内存空间,我觉得也没有多好。当然,处理起来可能比刚才那个转字符串完毕之后,然后再查询来的快。
然后我就我想到了我常用的Bitmap结构,0101啊,对吧,我只需要把如果说存在这个id,那么我把对应的位置置1即可,这样子增删改的速度全都加快了不是嘛。

当然,有一个缺点就是,查询Redis是有网络开销的。
但是我觉得如果使用Redis的bitmap,那么由于增删改查的速度都更快了,并且也不需要字符串的处理了,可能效果更优。

总结

这个方法只是我的思路,但是我马上就会动手去实现,敬请期待!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/639054.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

安卓期末考试知识总结

文章目录 第一章:Android基础入门习题总结重点知识 第二章:Android常见桌面布局&第三章:Android常见界面控件知识总结习题总结 第一章:Android基础入门 习题总结 Android系统采用分层架构,由高到低分为4层&#…

MySQL数据库 --- 运维篇

一、日志 1.1、错误日志 错误日志是 MySQL 中最重要的日志之一,它记录了当 mysqld 启动和停止时,以及服务器在运行过程中发生任何严重错误时的相关信息。当数据库出现任何故障导致无法正常使用时,建议首先查看此日志。 该日志是默认开启的…

实训笔记6.12

实训笔记6.12 6.12一、座右铭二、知识回顾2.1 面向对象的两大核心概念:类和对象2.2 面向对象的三大特征封装性继承性多态性-必须在继承之上抽象性 2.3 面向对象的常用关键字2.4 Java设计模式中适配器模式2.4.1 接口适配器2.4.2 类适配器2.4.3 对象适配器 三、Java常…

Linux基础知识3

Linux基础知识 适合有Linux基础的人群进行复习。 禁止转载! 用户与用户组管理 Linux系统下的3类用户和功能; 答: root用户(或称根用户、超级用户):Linux的内置用户,权限最高,具有…

wps安装提示nsis error

1.安装时弹出「NSIS error」错误框,无法安装。 此问题为一般为安装包损坏导致,可重新下载安装包尝试安装。 我遇到的提示也是这个。文件损坏。但是换了绿色U盘(格式是FAT32)复制过去就能安装。 之前用白色U盘(格式是N…

一学就会-----链表的回文结构

文章目录 题目描述思路代码示例 题目描述 对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构。 给定一个链表的头指针A,请返回一个bool值,代表其是否为回文结构。保证链表长度小于等于90…

1.1 搭建Scala开发环境

一、Windows上安装Scala (一)到Scala官网下载Scala Scala2.13.10下载网址:https://www.scala-lang.org/download/2.13.10.html 单击【scala-2.13.10.msi】超链接,将scala安装程序下载到本地 (二)安装…

Atcoder Beginner Contest 305

A - Water Station AC代码&#xff1a; #include<iostream> #include<algorithm> #include<cstring> using namespace std; int main() {int n;cin>>n;int a,b;for(int in;;i){if(i%50){ai;break;}}for(int in;;i--){if(i%50){bi;break;}}if(a-n<…

【Linux学习】多线程——线程池 | 单例模式

&#x1f431;作者&#xff1a;一只大喵咪1201 &#x1f431;专栏&#xff1a;《Linux学习》 &#x1f525;格言&#xff1a;你只管努力&#xff0c;剩下的交给时间&#xff01; 线程池 | 单例模式 一、 线程池1.1 Thread.hpp1.2 ThreadPool.hpp1.3 main.cpp1.4 RAII方式加锁 …

苹果的Safari私人浏览现在会自动删除URL中的跟踪参数

苹果将对Safari私人浏览器进行重大更新&#xff0c;为用户提供更好的保护&#xff0c;防止他们在浏览网页时被第三方跟踪。 苹果公司表示:“先进的追踪和指纹保护功能可以进一步防止网站利用最新技术追踪或识别用户的设备。” “隐私浏览现在在不使用时锁定&#xff0c;允许用…

百收网SEO问卷调查赚钱项目介绍

百收网SEO问卷调查赚钱项目介绍 大家好&#xff0c;我是百收网SEO 给面子的 也可以叫狂潮哥 哈哈哈哈 认识我比较久的朋友都知道我们做问卷调查项目3年多了这个生意基本没有在朋友圈发过 原因是靠我们自己做 单人一个月就可以产值1到4W 根本没想去收学员 直到看到同行在收学…

基于postman进行接口测试实战

一&#xff1a;接口测试前准备 接口测试是基于协议的功能黑盒测试&#xff0c;在进行接口测试之前&#xff0c;我们要了解接口的信息&#xff0c;然后才知道怎么来测试一个接口&#xff0c;如何完整的校验接口的响应值。 那么问题来了&#xff0c;那接口信息从哪里获取呢&…

加速数字化转型,通过零代码ETL工具实现吉客云数据自动化同步

一、吉客云系统介绍 吉客云是一家SaaS企业服务提供商&#xff0c;主要提供企业级应用服务。吉客云的服务范围涵盖了企业级推广、企业级智能客服、企业级销售管理、企业级客户关系管理、企业级电子商务等方面的服务&#xff0c;并且提供了基于AI技术的解决方案。其目标是通过数…

Maven教程--下(包括手动实现)

Maven教程–下&#xff08;包括手动实现&#xff09; 前言 注意本篇是需要一定的maven基础的 如果没有请移步Maven教程–上 手动创建Maven 项目- 理解Maven 底层机制 需求说明/图解 用手工的方式&#xff0c;创建maven 项目&#xff0c; 深刻理解Maven 工作机制 完成功能…

【Map集合的获取功能】

Map集合的获取功能 V get(Object Key)&#xff1a;根据键获取值 package com.gather.map; //Map集合的获取功能 import java.util.HashMap; import java.util.Map; public class MapDemo03 {public static void main(String[] args) {Map<String,String> mapnew HashMap&…

一步步搭建基于 ts + express + prisma + mongodb + zod 后端服务

环境&#xff1a; windows11、node 18.16.0 、pnpm 1、在合适位置&#xff0c;代开 vscode , 终端执行 mkdir miaooo-backend && cd miaooo-backend && npm init -y 。 创建一个名为一个 miaooo-backend 的项目&#xff0c;并且进入项目 执行 npm 默认初始化。…

【SpringCloud——Seata分布式事务管理框架】

一、分布式事务存在的问题 在分布式系统下&#xff0c;一个业务跨越多个服务或数据源&#xff0c;每个服务都是一个分支事务&#xff0c;要保证所有分支事务最终状态一致&#xff0c;这样的事务就是分布式事务。 分布式事务和传统形式的事务区别有什么&#xff1f;众所周知&a…

【GIS教程】使用高程数据在UE5中创建真实山脉模型

在数字孪生项目中&#xff0c;我们经常需要使用真实的山脉地形作为城市模型展示的基础。然而&#xff0c;UE5的默认地形系统过于复杂&#xff0c;无法像3D模型那样进行实时修改。因此&#xff0c;本教程将指导您如何将高程山脉作为模型导入到UE5引擎中&#xff0c;而不是使用UE…

【微服务】SpringBoot 插件化开发模式详细总结

目录 一、前言 1.1 使用插件的好处 1.1.1 模块解耦 1.1.2 提升扩展性和开放性 1.1.3 方便第三方接入 1.2 插件化常用实现思路 二、Java常用插件实现方案 2.1 serviceloader方式 2.1.1 java spi 2.1.2 java spi 简单案例 2.2 自定义配置约定方式 2.2.1 添加配置文件…

36.SpringBoot实用篇—运维

目录 一、实用篇—运维。 &#xff08;1&#xff09;程序打包与运行&#xff08;Windows版&#xff09;。 &#xff08;2&#xff09;spring-boot-maven-plugin插件作用。 &#xff08;3&#xff09;程序打包与运行&#xff08;Linux版&#xff09;。 &#xff08;4&#…