• 请不要在回答技术问题时复制粘贴 AI 生成的内容
brader
V2EX  ›  程序员

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

  •  
  •   brader · May 26, 2022 · 6856 views
    This topic created in 1626 days ago, the information mentioned may be changed or developed.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    最后一个问题叫 Feature ,智能模糊搜索,>_<
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   732 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 78ms · UTC 19:43 · PVG 03:43 · LAX 11:43 · JFK 14:43
    ♥ Do have faith in what you're doing.