如何低成本解决模糊搜索问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
brader
V2EX    程序员

如何低成本解决模糊搜索问题

  •  
  •   brader 2022-05-26 17:43:58 +08:00 5640 次点击
    这是一个创建于 1240 天前的主题,其中的信息可能已经有所发展或是发生改变。

    用的 mysql 数据库,有时候做业务,动不动产品就会说,这个字段我要模糊搜索。 实在不想大费周章,直接用的 like ,前期还好,到了后面跑不动,还有没有其他低成本的替代方案?

    53 条回复    2022-06-01 23:02:39 +08:00
    danbai
        1
    danbai  
    PRO
       2022-05-26 17:45:40 +08:00
    最近刚好用到了一个搜索引擎,https://www.meilisearch.com/
    Jooooooooo
        2
    Jooooooooo  
       2022-05-26 17:45:42 +08:00
    搞个 es 吧
    brader
        3
    brader  
    OP
       2022-05-26 17:48:07 +08:00
    @Jooooooooo 成本太高了啊,要知道,我们一个后台列表页的需求,按小时算的,就给 2-3 小时工时,去折腾 es ,绩效做不出来
    SjwNo1
        4
    SjwNo1  
       2022-05-26 17:48:41 +08:00
    mysql ngram
    Red998
        5
    Red998  
       2022-05-26 17:50:48 +08:00
    like 的话使用前缀索引好点 、
    Jooooooooo
        6
    Jooooooooo  
       2022-05-26 17:52:32 +08:00
    @brader 那只有改需求一个法子了. 比如只搜一段时间内的, 数据会少点.
    ragnaroks
        7
    ragnaroks  
       2022-05-26 17:52:57 +08:00
    只读从库
    brader
        8
    brader  
    OP
       2022-05-26 17:53:03 +08:00
    @redorblacck886 产品不让,就是要模糊搜索效果
    liaohongxing
        9
    liaohongxing  
       2022-05-26 17:54:15 +08:00
    mysql ngram 全文,最方便的了
    brader
        10
    brader  
    OP
       2022-05-26 17:55:15 +08:00
    @liaohongxing 这个好像方便,如果我用自带的全文索引,不装 ngram 这个插件,模糊查找会出什么问题吗?
    pengtdyd
        11
    pengtdyd  
       2022-05-26 17:56:19 +08:00
    需求评审没人提这个问题 ???
    liaohongxing
        12
    liaohongxing  
       2022-05-26 17:57:07 +08:00
    大哥 ngram 是 mysq8 内置插件。都不需要装 ,支持中文 ,简单几下就配起来的。不想麻烦,就这个最简单 。比 like 强一点
    brader
        13
    brader  
    OP
       2022-05-26 17:58:13 +08:00
    @pengtdyd 那帮蠢货从来不开需求评审,需求时间评估也不让开发评估,都是产品或测试一口价定的时间
    encro
        14
    encro  
       2022-05-26 17:58:14 +08:00   1
    Mysql 中文全文索引(含实例 5 分钟上手)

    https://c4ys.com/archives/2098
    brader
        15
    brader  
    OP
       2022-05-26 17:58:56 +08:00
    @liaohongxing 8 好遥远啊,我们还是 5.6 还是 5.7 来着
    wellerman
        16
    wellerman  
       2022-05-26 18:01:06 +08:00
    简单点就用空间换时间,提取关键词(或全部分词),弄个索引。再顶不住了就只有上 ES 了。
    MoYi123
        17
    MoYi123  
       2022-05-26 18:03:25 +08:00
    换 pg,用 gin 索引
    cowwa
        18
    cowwa  
       2022-05-26 18:10:56 +08:00
    搞个 Redi 缓存起来
    teel
        19
    teel  
       2022-05-26 18:12:29 +08:00 via iPhone
    如果数据量不是特别大的话,把列表内需要搜索的字段全部拉取到前端用 Fuse.js 做模糊搜索。前提是数据量不能太大。
    PS:不让开发评估时间的公司还是尽早走吧
    dzdh
        20
    dzdh  
       2022-05-26 18:16:31 +08:00
    刚在隔壁帖子里看到了个 zinc https://github.com/zinclabs/zinc

    已经在自己的小机器上跑起来了。

    meilisearch 自己测试了 1kw 数据服务器内存撑不住了。

    要长治久安就用 postgresql 吧,装个 zhparser 还能指定分词和词库。
    sadfQED2
        21
    sadfQED2  
       2022-05-26 18:19:06 +08:00 via Android   1
    5.6 5.7 的 mysql ,不用 es ,不用 like ,那你手动拆词,然后在 mysql 里面建一张表当倒排索引?相当于用 mysql 实现一个简易版的 es

    不然的话就找那些奇奇怪怪的 mysql 插件或者存储引擎?但是这种稳定性就不敢保证了

    最后,人和代码有一个能跑就行,没有需求评审,也没有技术评审,上线时间拍脑袋决定,我觉得该你跑了
        22
    Latin  
       2022-05-26 18:19:34 +08:00
    上个 elasticsearch 解君忧
    3kkkk
        23
    3kkkk  
       2022-05-26 18:23:41 +08:00
    如果没用过,上面哪种方案用到生产都不是几个小时搞定的。 让产品需求做技术调研,不给时间就让他们自己搞你把上面方案给罗列了。
    Buges
        24
    Buges  
       2022-05-26 18:24:04 +08:00 via Android
    当然是 meilisearch ,简单轻量,适合小规模数据。
    clf
        25
    clf  
       2022-05-26 18:25:05 +08:00
    搜索的时候加上数据量限制?不返回有多少条符合结果的 total 。

    前缀搜索的效率会高很多,能走索引。
    documentzhangx66
        26
    documentzhangx66  
       2022-05-26 18:37:35 +08:00
    模糊搜索本来就是个成本高上天的事情,其成本比分词方案还要高,所以你这出发点就不对。

    你只能采用 有限度的分词 + 主动缓存 + 控制频次的方式,来降低成本,这种思路类似于剪枝,但仍然有一定成本。
    zamaojava
        27
    zamaojava  
       2022-05-26 18:42:16 +08:00
    不直接 run 吗,兄弟,我上家就是给我 精确 crud ,老子直接不干了
    monkeyWie
        28
    monkeyWie  
       2022-05-26 18:52:51 +08:00
    上 es 分词也难搞定,例如搜索一个字的时候
    nox42
        29
    nox42  
       2022-05-26 19:09:31 +08:00
    lucene
    yufeng0681
        30
    yufeng0681  
       2022-05-26 21:26:35 +08:00   4
    产品要快速出效果,3 小时的编码, 就只能用 like ,解决业务功能有无的问题;
    和项目经理说,后续肯定有性能问题,要解决就得技术 leader 上方案,给你们写业务代码的人用,或者单独给时间做这个性能需求。
    至于做不做,那就是项目经理决定。
    makdon
        31
    makdon  
       2022-05-26 22:03:36 +08:00
    看起来开发地位非常工具人呐,代码跟人有一个能跑就行
    westoy
        32
    westoy  
       2022-05-26 22:05:11 +08:00
    跑不动再说吧, like 至少能找到啊.....你分词+fulltext 调教不好, 很多词分错了找都找不到, 更麻烦.......
    marcojbk
        33
    marcojbk  
       2022-05-26 23:34:38 +08:00 via iPhone
    我其实有点没明白你说到了后面跑不动是什么意思,是说查询速度太慢,还是说无法实现比如多词中间加空格搜索的需求?
    brader
        34
    brader  
    OP
       2022-05-27 09:16:40 +08:00
    @wellerman 没有词意概念的,他们不需要分词效果,只要 like 那种模糊效果
    brader
        35
    brader  
    OP
       2022-05-27 09:18:31 +08:00
    @zamaojava 今年跑不了,有购房计划,跑也要过了今年
    brader
        36
    brader  
    OP
       2022-05-27 09:20:02 +08:00
    @marcojbk 用 Like 功能是完全对的,就是数据量多起来了,查询非常慢,我记得那个表,涨到 50 万,就不怎么查的动了
    meystack
      nbsp; 37
    meystack  
       2022-05-27 10:23:12 +08:00
    直接上 ES 或者迅搜,我有写好的类,在我开源的项目 swiftadmin 你在 fork 里面找下之前的备份,可以分分钟使用了,如不是很复杂,建议使用迅搜即可
    tickone
        38
    tickone  
       2022-05-27 13:23:08 +08:00
    可以试试这样查,扫描 name 索引,不是全表扫描,稍微好一点
    select * from table where id in (
    select id from table where name like '%哈哈%'
    )
    markgor
        39
    markgor  
       2022-05-27 14:24:47 +08:00
    这情况,不是应该转移问题吗...?
    前端增加 “等于”/“包含” 让用户选择,当使用包含慢的时候,说这是特性,嫌慢就用等于来筛选;或者搭建 ES 服务....
    让产品自己选择
    lizy0329
        40
    lizy0329  
       2022-05-27 15:06:15 +08:00
    @teel 后端弄个缓存,前端一拉就拉 1w 条数据,应该可以吧
    aikilan
        41
    aikilan  
       2022-05-27 16:05:18 +08:00
    你就在群里告诉产品这样会越来越慢呗,产品要是没意见,后果他就自己承担。
    Features
        42
    Features  
       2022-05-27 16:07:21 +08:00
    啊? 老版 discuz 不是有完善的方案吗?
    1.限制字数
    2.限制搜索频率
    3.必须登录后搜索
    还有很多我都忘记了
    zhangwugui
        43
    zhangwugui  
       2022-05-27 16:08:21 +08:00
    mysql5.7 的 ngram 尝试过,我记得是有点问题的:
    1 )有些高频数据可能搜不到;
    2 )搜索时间可能时快时慢,
    3 )查询条件过长,还可能触发 cache limit ;
    raptor
        44
    raptor  
       2022-05-27 16:09:26 +08:00
    30 楼正解,得让产品知道每个需求都是有成本的,实现模糊查询是一个成本,实现高性能的模糊查询是另一个成本。
    hatsuyuki
        45
    hatsuyuki  
       2022-05-27 16:10:40 +08:00
    小规模数据 meilisearch 最合适,性能高,消耗少
    dog82
        46
    dog82  
       2022-05-27 16:59:31 +08:00
    这个帖子有营养,大家思路好广
    donfisher
        47
    donfisher  
       2022-05-27 17:03:03 +08:00
    1. mysql 做全文索引
    2. 果断上 es
    brader
        48
    brader  
    OP
       2022-05-27 17:09:36 +08:00
    @meystack 请问下你这个迅搜项目,可以有自带组件解决 mysql 表数据的全量同步和增量同步的增删改 同步方案吗?还是要自己通过代码进行推送
    meystack
        49
    meystack  
       2022-05-27 18:21:57 +08:00
    @brader 那没有,如果需要同步的话,有两种方案

    1 、在 PHP 读写的时候,如果有更新可以直接更新迅搜的数据,如果有并发的话就做队列
    2 、自己写 C 扩展去实现,xunsearch 其实就是监听了两个端口,只需要投递和查询相应的数据就行了,
    如果你们技术那边没问题,可以使用 mysql 类似的同步工具,自定义数据结构转换成 XS 对应的东西进行投递更新就行了
    这样可以脱离 PHP ;保持 mysql 同步
    Saxton
        50
    Saxton  
       2022-05-27 23:08:46 +08:00
    小公司不要上 ES ,你确定公司能给你提供好的服务器资源?,到头来资源不够还天天炸,meilisearch 也可以考虑下,如果真想在压低成本就像楼上说的只读从库,也可以考虑 mysql 的分词,虽然不咋样但勉强可以满足需求。
    heyjei
        51
    heyjei  
       2022-05-28 10:36:26 +08:00   2
    当年用 PHP 搞论坛的时候,那时还没有 ES ,分词也没有这么方便。

    PHPBB 有一个骚操作叫基于二分分词的倒排索引,不管是搜索的准确性和速度,效果都很不错。特别适合你这种情况。

    思路就是把一篇文章的按两两分词插入到另外一张倒排索引表,然后搜的时候,把搜索词也二分分词,去查那张倒排表。

    两两分词的意思就是:当年用 PHP 搞论坛的时候 可以分词为:当年、年用、用 P 、PH 、HP 、P 搞、搞论、论坛、坛的、的时、时候。

    适合这种文章的数量比较少的情况。
    zhangwugui
        52
    zhangwugui  
       2022-06-01 10:27:05 +08:00
    @heyjei 这个之前尝试过,这种方式是 分词+倒排索引,最后两张表进行关联,我最近进行测试,发现这种有三个小问题:
    1 )分词表会很大;
    2 )单个汉字进行搜索有问题(可以从产品端避免)
    3 )文章内容有回文的情况查询会有问题;

    中国商标专利事务所有限公司务专

    搜:"专利事务", 查询过滤为:IN ('专利','利事','事务'),能正常搜出来;
    搜:"事务专利", 查询过滤为:IN ('事务','务专','专利'),也能搜出来,但正常是搜不到这条数据;
    heyjei
        53
    heyjei  
       2022-06-01 23:02:39 +08:00
    @zhangwugui 第一个问题其实还好,常用汉字就 2500 字,两两组合也就 6250000 行

    最后一个问题叫 Feature ,智能模糊搜索,>_<
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2911 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 90ms UTC 06:15 PVG 14:15 LAX 23:15 JFK 02:15
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86