› 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 · Jan 2, 2020 · 5132 views
    This topic created in 2462 days ago, the information mentioned may be changed or developed.
    需求是这样的,搜索关键字有可能是词组,期望搜索出来的结果包含整个词组(即不分词),但可以带后缀通配符。

    比如:搜索 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……
    Supplement 1  ·  Jan 2, 2020

    更新下:
    如果 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 replies  •  2020-01-03 17:34:37 +08:00
    simapple
        1
    simapple  
       Jan 2, 2020
    也算不上 bug, 你搜索 helloworld* 就好了,不要留出空格
    reidxx
        2
    reidxx  
       Jan 2, 2020
    楼主用 mysql 的全文索引怎么处理中文问题的?
    wangyzj
        3
    wangyzj  
       Jan 2, 2020
    我觉得你要用 mysql fulltext 就别太纠结他的分词把
    或者自己挂一个分词插件
    xianyu0
        4
    xianyu0  
    OP
       Jan 2, 2020
    @simapple
    搜 helloworld* 得不到 `hello world' 这样的结果吧

    @reidxx
    我搜索的内容全是英文的,mysql5.6+之后不是引入了 ngram 了吗?已经支持中文分词了吧,不过貌似是比较简单的分词
    klaudy
        5
    klaudy  
       Jan 3, 2020 via Android
    mysql 正则表达式
    simapple
        6
    simapple  
       Jan 3, 2020
    @xianyu0 哦 没看清问题,我试了一下 match(content) against('"hello world"' in boolean mode) 这样搜,可以匹配到 hello world 和 hello worlds
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   2933 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 12:42 · PVG 20:42 · LAX 05:42 · JFK 08:42
    ♥ Do have faith in what you're doing.