V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
MySQL 5.5 Community Server
MySQL 5.6 Community Server
Percona Configuration Wizard
XtraBackup 搭建主从复制
Great Sites on MySQL
Percona
MySQL Performance Blog
Severalnines
推荐管理工具
Sequel Pro
phpMyAdmin
推荐书目
MySQL Cookbook
MySQL 相关项目
MariaDB
Drizzle
参考文档
http://mysql-python.sourceforge.net/MySQLdb.html
xianyu0
V2EX  ›  MySQL

关于 mysql 全文检索的分词和 wildcard

  •  
  •   xianyu0 · 2020-01-02 12:08:49 +08:00 · 3968 次点击
    这是一个创建于 1812 天前的主题,其中的信息可能已经有所发展或是发生改变。
    需求是这样的,搜索关键字有可能是词组,期望搜索出来的结果包含整个词组(即不分词),但可以带后缀通配符。

    比如:搜索 hello world
    期望结果包括:
    hello world
    hello worlds
    不包括:
    hello xxx world

    mysql 的全文检索通过 double quote 阻止分词,但是在 double quote 里无法使用 wildcard,
    比如 match(c) against('"hello world*"' in boolean mode) 的搜索结果并不包含 hello worlds。

    这个貌似是 mysql 的 bug,搜到这个 issue: https://bugs.mysql.com/bug.php?id=80723

    不知是否有办法绕过(暂不考虑 elasticsearch……
    第 1 条附言  ·  2020-01-02 17:08:31 +08:00

    更新下:
    如果 wildcard 只出现在词组最后,也就是:
        match(xxx) against('+key1 +key2*' in boolean mode)
    不要求每一个词后面都带 wildcard:
        match(xxx) against('+key1* +key2*' in boolean mode)
    而且搜出来的结果不多的话,可以考虑用like作二次过滤:
        select xxx from (
            select xxx from t where match(xxx) against('+key1 +key2*' in boolean mode)
        ) as s
        where s.xxx like '%key1 key2%'

    6 条回复    2020-01-03 17:34:37 +08:00
    simapple
        1
    simapple  
       2020-01-02 15:21:52 +08:00
    也算不上 bug, 你搜索 helloworld* 就好了,不要留出空格
    reidxx
        2
    reidxx  
       2020-01-02 15:40:28 +08:00
    楼主用 mysql 的全文索引怎么处理中文问题的?
    wangyzj
        3
    wangyzj  
       2020-01-02 16:31:21 +08:00
    我觉得你要用 mysql fulltext 就别太纠结他的分词把
    或者自己挂一个分词插件
    xianyu0
        4
    xianyu0  
    OP
       2020-01-02 16:56:09 +08:00
    @simapple
    搜 helloworld* 得不到 `hello world' 这样的结果吧

    @reidxx
    我搜索的内容全是英文的,mysql5.6+之后不是引入了 ngram 了吗?已经支持中文分词了吧,不过貌似是比较简单的分词
    klaudy
        5
    klaudy  
       2020-01-03 08:44:47 +08:00 via Android
    mysql 正则表达式
    simapple
        6
    simapple  
       2020-01-03 17:34:37 +08:00
    @xianyu0 哦 没看清问题,我试了一下 match(content) against('"hello world"' in boolean mode) 这样搜,可以匹配到 hello world 和 hello worlds
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3051 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 13:57 · PVG 21:57 · LAX 05:57 · JFK 08:57
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.