zoukankan      html  css  js  c++  java
  • MySQL全文本搜索

    启动全文本搜索

    CREATE TABLE productnotes
    {
        node_id int NOT NULL AUTO_INCREMENT,
        prod_id char(10) NOT NULL,
        note_date datetime NOT NULL,
        note_text text NULL,
        PRIMARY KEY(note_id),
        FULLTEXT(note_text)
    }ENGINE=MyISAM;
    
    • 这些列中有一个名为note_text的列,为了进行全文本搜索,MySQL根据子句FULLTEXT(note_text)的指示对它进行索引。这里的FULLTEXT索引单个列,如果需要也可以指定多个列。
    • 在定义之后,MySQL自动维护该索引。在增加、更新或删除行时,索引随之自动更新。
    • 可以在创建表时指定FULLTEXT,或者在稍后指定(在这种情况下所有已有数据必须立即索引)。

    进行全文本搜索

    mysql> SELECT note_text 
           FROM productnotes 
           WHERE Match(note_text) Against('rabbi')
    +------------------------------------------------------------------------------------------+
    | note_text                                                                                |
    +------------------------------------------------------------------------------------------+
    | Customer complaint: rabbit has been able to detect trap, food apparently less effective now.                             |
    | Quantity varies, sold by the sack load.All guaranteed to be bright and orange, and suitable for use as rabbit bait. |
    +------------------------------------------------------------------------------------------+
    2 rows in set (0.03 sec)
    
    • Match()指定被搜索的列,Against()指定要使用的搜索表达式。
    • 使用完整的 Match() 说 明 传递给 Match() 的值必须与FULLTEXT()定义中的相同。如果指定多个列,则必须列出它们(而且次序正确)。
    • 搜索不区分大小写 除非使用BINARY方式,否则全文本搜索不区分大小写。

    全文本匹配等级

    select note_text,match(note_text) AGAINST('rabbit')AS rank FROM productnotes;
    
    • Match()和Against()用来建立一个计算列(别名为rank),此列包含全文本搜索计算出的等级值。等级由MySQL根据行中词的数目、唯一词的数目、整个索引中词的总数以及包含该词的行的数目计算出来。正如所见,不包含词rabbit的行等级为0(因此不被前一例子中WHERE子句选择)。确实包含词rabbit的两个行每行都有一个等级值,文本中词靠前的行的等级值比词靠后的行的等级值高。

    • 排序多个搜索项 如果指定多个搜索项,则包含多数匹配词的那些行将具有比包含较少词(或仅有一个匹配)的那些行高的等级值。

    使用查询扩展

    SELECT note_text FROM productnotes Match(note_text) Against('anvils' WITH QUERY EXPANSION);
    

    在这里插入图片描述

    • 这次返回了7行。第一行包含词anvils,因此等级最高。第二行与anvils无关,但因为它包含第一行中的两个词(customer和recommend),所以也被检索出来。第3行也包含这两个相同的词,但它们在文本中的位置更靠后且分开得更远,因此也包含这一行,但等级为第三。第三行确实也没有涉及anvils(按它们的产品名)。
    • 正如所见,查询扩展极大地增加了返回的行数,但这样做也增加了你实际上并不想要的行的数目。

    布尔文本搜索[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ORwwE0Dh-1592563655670)(/home/cmf/.config/Typora/typora-user-images/image-20200619184012720.png)]

    • 然匹配词heavy,但-rope明确地指示MySQL排除包含rope

    全文本布尔操作符

    布 尔 操 作 符 说 明
    + 包含,词必须存在
    - 排除,词必须不出现
    > 包含,而且增加等级值
    < 包含,且减少等级值
    () 把词组成子表达式(允许这些子表达式作为一个组被包含、排除、排列等)
    ~ 取消一个词的排序值
    * 词尾的通配符
    "" 定义一个短语(与单个词的列表不一样,它匹配整个短语以便包含或排除这个短语)

    全文本搜索的使用说明

    • 索引全文本数据时,短词被忽略且从索引中排除。短词定义为那些具有3个或3个以下字符的词(如果需要,这个数目可以更改)。
    • MySQL带有一个内建的非用词(stopword)列表,这些词在索引全文本数据时总是被忽略。如果需要,可以覆盖这个列表(请参阅MySQL文档以了解如何完成此工作)。
    • 许多词出现的频率很高,搜索它们没有用处(返回太多的结果)。因此,MySQL规定了一条50%规则,如果一个词出现在50%以上的行中,则将它作为一个非用词忽略。50%规则不用于IN BOOLEAN MODE。
    • 如果表中的行数少于3行,则全文本搜索不返回结果(因为每个词或者不出现,或者至少出现在50%的行中)。
    • 忽略词中的单引号。例如,don't索引为dont。
    • 不具有词分隔符(包括日语和汉语)的语言不能恰当地返回全文本搜索结果。
    • 如前所述,仅在MyISAM数据库引擎中支持全文本搜索。
  • 相关阅读:
    【PAT甲级】1043 Is It a Binary Search Tree (25 分)(判断是否为BST的先序遍历并输出后序遍历)
    Educational Codeforces Round 73 (Rated for Div. 2)F(线段树,扫描线)
    【PAT甲级】1042 Shuffling Machine (20 分)
    【PAT甲级】1041 Be Unique (20 分)(多重集)
    【PAT甲级】1040 Longest Symmetric String (25 分)(cin.getline(s,1007))
    【PAT甲级】1039 Course List for Student (25 分)(vector嵌套于map,段错误原因未知)
    Codeforces Round #588 (Div. 2)E(DFS,思维,__gcd,树)
    2017-3-9 SQL server 数据库
    2017-3-8 学生信息展示习题
    2017-3-5 C#基础 函数--递归
  • 原文地址:https://www.cnblogs.com/chengmf/p/13164613.html
Copyright © 2011-2022 走看看