精华内容
下载资源
问答
  • MySQL中文全文检索

    2021-01-18 23:15:07
    一、概述MySQL全文检索是利用查询关键字和查询列内容之间的相关度进行检索,可以利用全文索引来提高匹配的速度。二、语法例如:SELECT * FROM tab_name WHERE MATCH ('列名1,列名2...列名n') AGAINST('词1 词2 词3 ....

    一、概述

    MySQL全文检索是利用查询关键字和查询列内容之间的相关度进行检索,可以利用全文索引来提高匹配的速度。

    二、语法

    例如:SELECT * FROM tab_name WHERE MATCH ('列名1,列名2...列名n') AGAINST('词1 词2 词3 ... 词m');

    即:MATCH 相当于要匹配的列,而 AGAINST 就是要找的内容。

    这里的table需要是MyISAM类型的表,col1、col2 必须是char、varchar或text类型,在查询之前需要在 col1 和 col2 上分别建立全文索引(FULLTEXT索引)。

    三、检索方式

    1、自然语言检索: IN NATURAL LANGUAGE MODE

    2、布尔检索: IN BOOLEAN MODE

    剔除一半匹配行以上都有的词,譬如说,每个行都有this这个字的话,那用this去查时,会找不到任何结果,这在记录条数特别多时很有用,原因是数据库认为把所有行都找出来是没有意义的,这时,this几乎被当作是stopword(中断词);但是若只有两行记录时,是啥鬼也查不出来的,因为每个字都出现50%(或以上),要避免这种状况,请用IN BOOLEAN MODE。

    IN BOOLEAN MODE的特色:

    ·不剔除50%以上符合的row。

    ·不自动以相关性反向排序。

    ·可以对没有FULLTEXT index的字段进行搜寻,但会非常慢。

    ·限制最长与最短的字符串。

    ·套用Stopwords。

    搜索语法规则:

    +   一定要有(不含有该关键词的数据条均被忽略)。

    -   不可以有(排除指定关键词,含有该关键词的均被忽略)。

    >   提高该条匹配数据的权重值。

    ~   将其相关性由正转负,表示拥有该字会降低相关性(但不像 - 将之排除),只是排在较后面权重值降低。

    *   万用字,不像其他语法放在前面,这个要接在字符串后面。

    " " 用双引号将一段句子包起来表示要完全相符,不可拆字。

    3、查询扩展检索: WITH QUERY EXPANSION

    四、MySQL全文检索的条件限制

    1、在MySQL5.6以下,只有MyISAM表支持全文检索。在MySQL5.6以上Innodb引擎表也提供支持全文检索。

    2、相应字段建立FULLTEXT索引

    五、与全文检索相关的系统变量:

    ft_min_word_len = 全文检索的最小许可字符(默认4,通过 SHOW VARIABLES LIKE 'ft_min_word_len' 可查看),中文通常是两个字就是一个词,所以做中文的话需要修改这个值为2最好。

    六、总结事项

    1、预设搜寻是不分大小写,若要分大小写,columne 的 character set要从utf8改成utf8_bin。

    2、预设 MATCH...AGAINST 是以相关性排序,由高到低。

    3、MATCH(title, content)里的字段必须和FULLTEXT(title, content)里的字段一模一样。

    如果只要单查title或content一个字段,那得另外再建一个 FULLTEXT(title) 或 FULLTEXT(content),也因为如此,MATCH()的字段一定不能跨table,但是另外两种搜寻方式好像可以。

    4、MySQL不支持中文全文索引,原因很简单:与英文不同,中文的文字是连着一起写的,中间没有MySQL能找到分词的地方,截至目前MySQL5.6版本是如此,但是有变通的办法,就是将整句的中文分词,并按urlencode、区位码、base64、拼音等进行编码使之以“字母+数字”的方式存储于数据库中。

    七、实验部分

    ◆ 步骤1 配置my.ini,在my.ini末尾添加如下:

    # 修改全文检索的最小许可字符为2个字符或汉字 ft_min_word_len = 2

    完成后“重启 MySQL 服务”,并用 SHOW VARIABLES LIKE 'ft_min_word_len' 查询下是否得到了正确的结果值为2,如下图:

    e254b476e17437d74b97ded5c32f0379.png

    ◆ 步骤2 创建数据库(视情况可跳过此步)

    ◆ 步骤3 创建数据表

    # 如果后期需要添全文加索引可以用如下语句:

    ◆ 步骤4 插入测试数据

    插入结果如下图:

    559c3748abfe077eeac6fb03184c53cf.png

    ◆ 步骤5 搜索语法规则、排序 实验

    说明:匹配语句 MATCH (col1,col2,...) AGAINST (expr [search_modifier]) 匹配完成后,会返回此条数据的权重值(权重值1 ≈ 各个词的匹配结果权重值之和),我们利用此权重值“由高到低”排序可优化查询结果。

    ------------------------------------------------------------------------------------------------------------------------------

    ▶ 实验1:只对 title_fc 索引字段做全文检索,并显示每条数据的权重值

    388b3d3f59964ff74410450455db50f4.png

    总结:

    1.当没有加 + - 这样的过滤符号时,这些关键词是“或(or)”的关系,即:要么匹配optimizing,要么匹配ok,要么匹配red,要么匹配blue。

    2.通过上面实验,发现当某条数据有多个关键词匹配时(如:red blue),此条数据的权重值会略高:此条数据权重值 ≈ optimizing权重值 + ok权重值 + red权重值 + blue权重值理论上来说,当一条数据能匹配上的关键词越多,则此条数据的权重值越高,排名越靠前。

    ------------------------------------------------------------------------------------------------------------------------------

    ▶ 实验2:过滤条件:必须包含"red"关键词

    ab15ca8089d616631aaf6555d4c0db0c.png

    总结:使用了过滤符号 + ,表示查询结果中,任一条数据都必须包含"red"这个词,不包含"red"这个词的行均被忽略。

    ------------------------------------------------------------------------------------------------------------------------------

    ▶ 实验3:过滤条件:必须包含"red"关键词,如果匹配到的行中还含有"blue"关键词,则会对此条数据增加权重:

    或下面写法:

    d1027e5e07952cf4fa624c8acb3203ad.png

    总结:与实验2比较,当包含了red的行中,若也包含blue关键词,权重确实增加了(如:id=4这条)。

    ------------------------------------------------------------------------------------------------------------------------------

    ▶ 实验4:过滤条件:必须包含"red"关键词,并且不能包含"blue"关键词

    defd7ff6e13bdefc4cfd069bb7b19cf6.png

    总结:可见 + - 这两个符号是表示“并且(and)”的意思,即:必须包含red关键词 and 不能包含blue关键词。

    ------------------------------------------------------------------------------------------------------------------------------

    ▶ 实验5:过滤条件:必须包含"red"关键词,如果匹配到的行中还包含"blue"关键词则降低此条数据权重

    210d205a283eaf7f4ee8db5ae8f3182a.png

    总结:这个实验没有看到明显效果,但 ~ 过滤符确实是降低此权重符

    ------------------------------------------------------------------------------------------------------------------------------

    ▶ 实验6:过滤条件:匹配包含单词“red”和“Linux” 的行,或包含“red” 和“blue”的行(无先后顺序)然而包含 “apple Linux”的行较包含“apple blue”的行有更高的权重值。

    39b19107489dd42e50fba8a64c50608e.png

    ------------------------------------------------------------------------------------------------------------------------------

    ▶ 实验7:过滤条件:匹配关键词以 re 开头,或以 bl 开头的数据行

    e0965b5ef0eae6236f824444226008b3.png

    总结:注意 * 是写在后面哦,此时相当于 like 模糊匹配,没有权重值了

    ------------------------------------------------------------------------------------------------------------------------------

    ▶ 实验8:过滤条件:匹配查找字符串“To Use MySQL”关键词

    73709c50fb38b6b1331fa51f5955d03f.png

    总结:此时是把双引号内的的字符串看成一个关键词,若不用双引号则是将 To Use MySQL 三个关键词去分别匹配,两者有区别;

    ------------------------------------------------------------------------------------------------------------------------------

    ▶ 实验9:在实验1基础上,将blue的权重值忽视不要(注意与实验1比较)

    bd3b008c57d2477cf8011ac5d825f70e.png

    总结:在实验1的基础上,此时去除select字段条件里的blue关键词,但在where里去仍保留blue关键词。我的本意是想正常匹配“optimizing ok red blue”这几个关键词,但不想得到blue的权重值(忽视blue的权重值)。

    查询的结果是含有blue关键词的数据的权重值会略降低了。

    通过“降重”——忽略某些关键词权重值的方式可使部分数据权重值减小,进而影响排序。

    ------------------------------------------------------------------------------------------------------------------------------

    ▶ 实验10:在实验9的基础上,在select字段条件里增加几个red关键词,where里的关键词保持不变(注意与实验1 实验9比较)。

    12b39f3d7b3dd8629eff797660945feb.png

    总结:发现只要含有 red 关键词的数据的权重值都增加了,排序也发生了变化。说明通过“提重”——重复多次某些关键词权重值的方式可使部分数据权重值增加,进而影响排序。

    ------------------------------------------------------------------------------------------------------------------------------

    ▶ 实验11:同时对 title_fc 和 content_fc 两字段做全文检索

    18adb9bba51a56180701be087224f457.png

    总结:通过实验发现,又成功的取到了 content_fc 字段匹配的权重值,排序方式是首要按title字段权重降序排序,次要按 content_fc 权重降序排序。另外我发现 ok 这个关键词在对“title_fc char(254)”字段匹配时得到匹配值为2.1xxxxxxx,但对“content_fc text”字段匹配时权重值去为0,这是MySQL对各英文单词权重值的给予有自己的算法,我们无权干涉。所以当我们发现有些单词的权重值为零甚至为负时,不用过于纠结,因为MySQL有自己的算法。

    关于排序,首要按 title_score 字段权重降序排序,次要按 content_score 权重降序排序,这样的排序规则看起来更科学了,但我想优秀的搜索引擎绝不至于简单如此吧,继续下面的实验:

    -----------------------------------------------------------------------------------------------------------------------------

    ▶ 实验12:进一步优化 排序规则看一个SQL语句原型,查询“字段1,字段2”两字段,同时将每条数据的“字段1”与“字段2”的求和作为“字段3”字段:

    下面将 title_fc 和 content_fc 两权重值求和,放入新字段 score1 中,并按 score1 首要排序,title_score 次之,content_score再次之:

    48cf2b1861caef593ee42c99bed822e1.png

    总结:相对而言,如果 title_fc 和 content_fc 都匹配上了,应给予靠前的排名吧。所以首要按其 title_fc 和 content_fc 两权重值之和排名,次要再考虑 title_fc、content_fc 排序。

    ------------------------------------------------------------------------------------------------------------------------------

    ▶ 实验13:另一个角度看排序看一个SQL语句原型,如果性别字段值为“1”显示“男”否则显示“女”

    我的新排序思路:如果 title_fc 和 content_fc 同时匹配上的行做首要排序,然后对只匹配上 title_fc 的做次要排序,只匹配上 content_fc 的再次要排序。 (对于实验5的排序不科学之处在于:如果有一个对content_fc关键词的匹配权重很高,导致了求和后 score1 的值也高,但对title_fc的匹配权重去为0,由于score1值高却排到了前面这不一定科学吧?)

    0fd67548d13c6757cb630c175b2f823f.png

    总结:如果 title_fc 和 content_fc 都匹配上了,做为优先排序理所当然,但也应考虑局部权重值过高的问题哦。

    ------------------------------------------------------------------------------------------------------------------------------

    ▶ 实验14:优化实验13,可支持更复杂的条件排序看一个SQL语句原型,CASE WHEN THEN END 结构:

    有一表查询:大于或等于80表示显示为“优秀”,大于或等于60显示为“及格”,小于60分显示为“不及格”。

    # 实例测试一下

    我的新排序思路:如果 title_fc 和 content_fc 的权重值“同时大于0且相等”为首要排序,“同时大于0且不相等”的为次要排序,“title_fc 大于0的再次要排序”,如果用 IF() 貌似不好实现,看下面语句:

    3268a668d02dce0fe68d434a36a7c1b2.png

    总结:本实验的排序未必合乎科学,但引出一个更复杂规则的排序方式、角度,多种排序结合使用才能做出更合理的排序,才能使你的搜索引擎更加智能。抛砖引玉,或许你有更好的排序,请也分享给我。

    ------------------------------------------------------------------------------------------------------------------------------

    ▶ 实验15:中文全文检索

    MySQL不支持中文全文检索,因为中文一句话是连着写的,不像英文单词间有空格分隔。解决办法就是中文分词(关于中文分词请参阅其它文章),如果你的MySQL是安装在Windows平台上的,可以不用转码直接存储中文就可以使用全文索引,如本例。但是如果你的MySQL是安装在Linux上的则需要进行转编码(urlencode / base64_encode / json_encode / 区位 / 拼音)等方案,具体方案参看其它博文。

    7deb842aa93bd1f52f04eaf3337ecc95.png

    展开全文
  • 因为中文词间并没有明显的区隔,所以中文的分词是按照字典、词库的匹配和词的频度统计,或是基于句法、语法分析的分词,而MySQL并不具备此功能,所以MySQL对中文全文检索的支持几乎为零。目前很多网站和系统都提供了...

    因为中文词间并没有明显的区隔,所以中文的分词是按照字典、词库的匹配和词的频度统计,或是基于句法、语法分析的分词,而MySQL并不具备此功能,所以MySQL对中文全文检索的支持几乎为零。

    目前很多网站和系统都提供了全文搜索功能,用户可以输入词或者语句来定位匹配的记录。在后台,可以使用Select查询中的Like语句来执行这种查询,尽管这种方法可行,但对于全文查找而言,这是一种效率极端低下的方法,尤其在处理大量数据的时候。MySQL针对这一问题提供了一种基于内建的全文查找方式的解决方案。开发者只需要简单地标记出需要全文查找的字段,然后使用MySQL方法在那些字段运行搜索,这不仅仅提高了性能和效率(因为MySQL对这些字段做了索引来优化搜索),而且实现了更高质量的搜索,因为MySQL使用自然语言来智能地对结果评级,以去掉不相关的项目。这就是MySQL的全文检索功能。

    到MySQL3.23.23时,MySQL开始支持全文索引和搜索。全文索引在MySQL中是一个 FullText类型索引。FullText索引用于MyISAM表,可以在Create Table时或之后使用Alter Table或Create Index在Char、VarChar或TEXT列上创建。对于大的数据库,将数据装载到一个没有FullText索引的表中,然后再使用Alter Table (或Create Index) 创建索引,这将是非常快的。

    但是,众所周知,在英文排版时词间是以空格区分的,所以英文的分词是基于空格的。但是涉及到中文等东亚文字就没有这么简单了,因为中文词间并没有明显的区隔,所以中文的分词则是按照字典、词库的匹配和词的频度统计,或是基于句法、语法分析的分词,而MySQL并不具备此功能,所以MySQL对中文全文检索的支持几乎为零。

    需求及设计思想

    来自NetCraft统计的数据,截至2006年4月份全球网站数量超过8065万个,目前,Linux及Apache在网站操作系统及Web服务器软件市场的份额为62.7%。再来看一份来自中国互联网络信息中心(CNNIC)的调查报告,截至2006年1月1日,全国有69.4万个网站,在线数据库数为29万5400个。由于中国使用LAMP(Linux、Apache、MySQL、PHP)套件的数量没有达到世界平均份额,所以估计有15万左右的基于PHP/MySQL构架的网站,这不包括5万个WAP网站、企业管理系统、教学应用系统等信息管理系统。如果全都算上,在中国使用MySQL的站点(系统)数量应该在15万至18万之间。

    MySQL有如此庞大的使用规模,中文全文检索在MySQL的实现将是相当迫切,加之笔者在做一个网站系统的时候也是由于租用服务器硬性环境,不能自由选择数据库或者添加组件,所以只能根据已有的条件进行适应性改良。一个偶然的思路使笔者产生了能否将中文和英文建立特定关联,然后再进行检索呢?答案是可以的。MySQL不支持中文全文检索,但是支持英文全文检索,可以将“中文全文检索”转变为“英文全文检索”,然后再变回“中文全文检索”。那么中文又如何转换成英文呢?思路可以是:中文全文检索→拼音全文检索→中文全文检索。所以转换的思路如图1所示。

    0818b9ca8b590ca3270a3433284dd417.png

    图1 中文全文检索思路

    用户输入中文信息提交的时候,通过一个中文到拼音的转换程序将其数据转换为拼音的格式存入数据库中,然后用户检索时同样是输入中文,也将检索词转换为拼音,到数据库中进行匹配,返回结果。但是这样做有两个缺点:第一个是,检索是成功了,可是没有中文原数据,如何返回有效结果?第二个是,中文转换拼音如果中文篇幅过长,转换时间过长怎么办?所以催生了第二种解决方法,如图2所示。

    0818b9ca8b590ca3270a3433284dd417.png

    图2 改进后的检索思路

    如图2所示,用户输入中文按照正常方式直接提交至数据库,然后有一个后台转换程序循环执行,将中文转换为拼音存入另外一张全文检索表中,其他用户在进行全文检索时由于词语长度有限,所以可以采用即时转换拼音,然后进行数据库查询匹配。

    MySQL中文全文检索实现

    1.数据库表结构设计

    此处用到两张表,以为人员信息建立全文检索为例,分为:人员信息表(UserInfo)和全文检索表(IndexSeek),表结构如图3所示。

    0818b9ca8b590ca3270a3433284dd417.png

    图3 人员信息表和全文检索表

    人员信息表(UserInfo)各列含义为: ID(id),自增序列;姓名(user_name);个人介绍(user_introduction);全文检索状态(user_state),新添加或者修改后状态为0,拼音转换完成状态为1。

    全文检索表(IndexSeek) 各列含义为:ID(id),自增序列;关联人员信息ID(user_id),对应UserInfo表中ID;索引项(index_item),该列设置为FullText全文检索;索引标示(index_mark),标示为哪个列的索引,本文中涉及两个索引,分别为姓名(user_name)、介绍(user_introduction)。

    两个表中的log字段记录该行修改的时间和产生的错误提示。在本文中无实际用途。

    2.用户输入中文资料

    用户自己输入信息添加至数据库,例如,各项为:“1”、“张三”、“爱好编程,PHP,MySQL”、“0”。

    3.后台转换拼音过程

    后台应用程序按照规则进行中文到拼音的转换,笔者在网上下载了内码→拼音转换数据包pinyin.dat,该文件的下载网址为:http://scws.tguanlim.com/py/getpy.php。 以下以PHP代码为例演示中文→拼音转换。

    class my_Getpy

    {

    var $_dat = ''pinyin.dat'';

    var $_fd = false;

    function my_Getpy($pdat = '''')

    {

    if ('''' != $pdat)

    $this->_dat = $pdat;

    }

    function load($pdat = '''')

    {

    if ('''' == $pdat)

    $pdat = $this->_dat;

    $this->unload();

    $this->_fd = @fopen($pdat, ''rb'');

    if (!$this->_fd)

    {

    trigger_error("没有`$pdat`文件", E_USER_WARNING);

    return false;

    }

    return true;

    }

    function unload()

    {

    if ($this->_fd)

    {

    @fclose($this->_fd);

    $this->_fd = false;

    }

    }

    function get($zh)

    {

    /*if (strlen($zh) != 2)

    {

    trigger_error("`$zh` is not a valid GBK hanzi", E_USER_WARNING);

    return false;

    }*/

    if (!$this->_fd && !$this->load())

    return false;

    $high = ord($zh[0]) - 0x81;

    $low = ord($zh[1]) - 0x40;

    // 计算偏移位置

    $nz = ($ord0 - 0x81);

    $off = ($high< < 8) + $low - ($high * 0x40);

    // 判断 off 值

    fseek($this->_fd, $off * 8, SEEK_SET);

    $ret = fread($this->_fd, 8);

    $ret = rtrim($ret, ''\0'');

    return $ret;

    }

    function _my_Getpy()

    {

    $this->_unload();

    }

    }

    function csubstr($str,$start,$len)

    {

    $strlen=strlen($str);

    if ($start>=$strlen)

    return $str;

    $clen=0;

    for($i=0;$i< $strlen;$i++,$clen++)

    {

    if(ord(substr($str,$i,1))>0xa0)

    {

    if ($clen>=$start)

    $tmpstr.=substr($str,$i,2);

    $i++;

    }

    else

    {

    if ($clen>=$start)

    $tmpstr.=substr($str,$i,1);

    }

    if ($clen>=$start+$len)

    break;

    }

    return $tmpstr;

    }

    file://计算字符长度的函数,汉字中文都当作是长度为1

    function StrLenW($str)

    {

    $count = 0;

    $len = strlen($str);

    for($i=0; $i< $len; $i++,$count++)

    if(ord($str[$i])>=128)

    $i++;

    return $count;

    }

    file://批量中文转换拼音函数,转换后每个字符中间加上空格,判断非中文字符如符号,英文,数字则不作变动

    function operate_py($str){

    $len_max=StrLenW($str);

    $len="0";

    $start="0";

    $py = new my_Getpy;

    for($start=0;$start< $len_max;$start++){

    $simp=csubstr($str,$start,$len);

    if ( ord($simp)>127 ){

    $rs = $py->get($simp);

    $rs=" ".$rs." ";

    }

    else{

    $rs=$simp;

    }

    $rs_return.=$rs;

    }

    $py=null;

    return $rs_return;

    }

    将该程序循环执行,查询user_state为0的行,取出user_name、user_introduction两列数据,分别进行拼音转换,然后插入全文检索表(IndexSeek)表中,添加两行数据,其中第一行为:

    关联人员信息ID(user_id):1;//对应UserInfo表中ID,此处为1

    索引项(index_item):zhang1 san1;

    索引标示(index_mark): 姓名(user_name)。

    第二行为:

    关联人员信息ID(user_id):1;//对应UserInfo表中ID,此处为1

    索引项(index_item):ai4 hao3 bian1 cheng2 ,PHP,MySQL;

    索引标示(index_mark):介绍(user_introduction)。

    至此,添加中文数据转换拼音过程完毕。修改用户信息同样步骤进行,只是不再新添加表,删除数据则根据关联id全部删除。

    4.用户检索过程

    由于用户检索时输入的关键词数量有限,则采用页面应用程序直接转换拼音进行匹配。例如用户输入检索词为:“编程”,提交给服务器,由服务器端程序处理转换为“bian1 cheng2”进行数据表IndexSeek的全文检索,全文检索SQL为:

    SELECT * FROM IndexSeekWHERE MATCH (index_item) AGAINST ('' bian1 cheng2'');

    得出关联人员ID为1,然后取得用户资料表中全部信息返回给用户。由于中文转换拼音过程同上,在此不再列出代码。

    更多的英文全文检索技巧请参看MySQL手册,这里不再一一介绍。上面便是整个MySQL中文全文检索实现过程。

    本文所提供的方法并不能完全解决MySQL的全文检索问题,由于中文字词存在同音现象,比如:"清华"和"轻划"检索结果相同,这也是不可避免的,但是对于MySQL的用户来说,该方法是目前不错的一种折衷手段。

    展开全文
  • 这不,从MySQL 5.7开始,MySQL内置了ngram全文检索插件,用来支持中文分词,并且对MyISAM和InnoDB引擎有效。在使用中文检索分词插件ngram之前,先得在MySQL配置文件里面设置他的分词大小,比如,[...

    前言

    其实全文检索在MySQL里面很早就支持了,只不过一直以来只支持英文。缘由是他从来都使用空格来作为分词的分隔符,而对于中文来讲,显然用空格就不合适,需要针对中文语义进行分词。这不,从MySQL 5.7开始,MySQL内置了ngram全文检索插件,用来支持中文分词,并且对MyISAM和InnoDB引擎有效。

    在使用中文检索分词插件ngram之前,先得在MySQL配置文件里面设置他的分词大小,比如,

    [mysqld]

    ngram_token_size=2

    这里把分词大小设置为2。要记住,分词的SIZE越大,索引的体积就越大,所以要根据自身情况来设置合适的大小。

    示例表结构:

    CREATE TABLE articles (

    id INTUNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,

    titleVARCHAR(200),

    body TEXT,

    FULLTEXT (title,body) WITH PARSER ngram

    ) ENGINE=InnoDBCHARACTER SET utf8mb4;

    示例数据,有6行记录。

    mysql> select * from articles\G

    ***************************1. row ***************************

    id: 1

    title: 数据库管理

    body: 在本教程中我将向你展示如何管理数据库

    ***************************2. row ***************************

    id: 2

    title: 数据库应用开发

    body: 学习开发数据库应用程序

    ***************************3. row ***************************

    id: 3

    title: MySQL完全手册

    body: 学习MySQL的一切

    ***************************4. row ***************************

    id: 4

    title: 数据库与事务处理

    body: 系统的学习数据库的事务概论

    ***************************5. row ***************************

    id: 5

    title: NoSQL精髓

    body: 学习了解各种非结构化数据库

    ***************************6. row ***************************

    id: 6

    title: SQL 语言详解

    body: 详细了解如果使用各种SQL

    6 rows inset (0.00 sec)

    显式指定全文检索表源

    mysql> SETGLOBAL innodb_ft_aux_table="new_feature/articles";

    Query OK, 0 rows affected (0.00 sec)

    通过系统表,就可以查看到底是怎么划分articles里的数据。

    mysql> SELECT *FROM information_schema.INNODB_FT_INDEX_CACHE LIMIT 20,10;

    +------+--------------+-------------+-----------+--------+----------+

    | WORD | FIRST_DOC_ID | LAST_DOC_ID | DOC_COUNT | DOC_ID| POSITION |

    +------+--------------+-------------+-----------+--------+----------+

    | 中我 | 2 | 2 | 1 | 2 | 28 |

    | 习m | 4 | 4 | 1 | 4 | 21 |

    | 习了 | 6 | 6 | 1 | 6 | 16 |

    | 习开 | 3 | 3 | 1 | 3 | 25 |

    | 习数 | 5 | 5 | 1 | 5 | 37 |

    | 了解 | 6 | 7 | 2 | 6 | 19 |

    | 了解 | 6 | 7 | 2 | 7 | 23 |

    | 事务 | 5 | 5 | 1 | 5 | 12 |

    | 事务 | 5 | 5 | 1 | 5 | 40 |

    | 何管 | 2 | 2 | 1 | 2 | 52 |

    +------+--------------+-------------+-----------+--------+----------+

    10 rows in set (0.00 sec)

    这里可以看到,把分词长度设置为2,所有的数据都只有两个一组。上面数据还包含了行的位置,ID等等信息。

    接下来,我来进行一系列检索示范,使用方法和原来英文检索一致。

    一、自然语言模式下检索:

    1、得到符合条件的个数,

    mysql>SELECT COUNT(*) FROM articles

    -> WHERE MATCH (title,body) AGAINST ('数据库' IN NATURALLANGUAGE MODE);

    +----------+

    | COUNT(*) |

    +----------+

    | 4 |

    +----------+

    1 row in set (0.05 sec)

    2、得到匹配的比率,

    mysql>SELECT id, MATCH (title,body) AGAINST ('数据库' IN NATURAL LANGUAGE MODE)

    AS score FROM articles;

    +----+----------------------+

    | id| score |

    +----+----------------------+

    | 1 | 0.12403252720832825 |

    | 2 | 0.12403252720832825 |

    | 3 | 0 |

    | 4 | 0.12403252720832825 |

    | 5 | 0.062016263604164124|

    | 6 | 0 |

    +----+----------------------+

    6rows in set (0.00 sec)

    二、布尔模式下搜索,这个就相对于自然模式搜索来的复杂些:

    1、匹配既有管理又有数据库的记录,

    mysql> SELECT * FROM articles WHERE MATCH (title,body)

    -> AGAINST ('+数据库 +管理' IN BOOLEAN MODE);

    +----+------------+--------------------------------------+

    | id| title | body |

    +----+------------+--------------------------------------+

    | 1 | 数据库管理 | 在本教程中我将向你展示如何管理数据库 |

    +----+------------+--------------------------------------+

    1 rowin set (0.00 sec)

    2、匹配有数据库,但是没有管理的记录,

    mysql> SELECT * FROM articles WHERE MATCH (title,body)

    -> AGAINST ('+数据库 -管理' IN BOOLEAN MODE);

    +----+------------------+----------------------------+

    | id| title | body |

    +----+------------------+----------------------------+

    | 2 | 数据库应用开发 | 学习开发数据库应用程序 |

    | 4 | 数据库与事务处理 | 系统的学习数据库的事务概论 |

    | 5 | NoSQL 精髓 | 学习了解各种非结构化数据库 |

    +----+------------------+----------------------------+

    3 rows in set (0.00 sec)

    3、匹配MySQL,但是把数据库的相关性降低,

    mysql> SELECT * FROM articles WHERE MATCH (title,body)

    -> AGAINST ('>数据库 +MySQL' INBOOLEAN MODE);

    +----+---------------+-----------------+

    | id| title | body |

    +----+---------------+-----------------+

    | 3 | MySQL完全手册 |学习MySQL的一切 |

    +----+---------------+-----------------+

    1 rowin set (0.00 sec)

    三、查询扩展模式,比如要搜索数据库,那么MySQL,oracle,DB2也都将会被搜索到,

    mysql> SELECT * FROM articles

    -> WHERE MATCH (title,body)

    -> AGAINST ('数据库' WITH QUERY EXPANSION);

    +----+------------------+--------------------------------------+

    | id| title | body |

    +----+------------------+--------------------------------------+

    | 1 | 数据库管理 | 在本教程中我将向你展示如何管理数据库 |

    | 4 | 数据库与事务处理 | 系统的学习数据库的事务概论 |

    | 2 | 数据库应用开发 | 学习开发数据库应用程序 |

    | 5 | NoSQL 精髓 | 学习了解各种非结构化数据库 |

    | 6 | SQL 语言详解 | 详细了解如果使用各种SQL |

    | 3 | MySQL完全手册 | 学习MySQL的一切 |

    +----+------------------+--------------------------------------+

    6 rows in set (0.01 sec)

    当然,我这里只是功能演示,更多的性能测试,大家有兴趣可以进行详细测试。由于N-grm是中文检索常用的分词算法,已经在互联网大量使用,这次集成到MySQL中,想必效果上不会有太大的问题。

    总结

    以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

    展开全文
  • MySQL-中文全文检索

    2021-01-28 00:59:13
    一、概述MySQL全文检索是利用查询关键字和查询列内容之间的相关度进行检索,可以利用全文索引来提高匹配的速度。二、语法例如:SELECT * FROM tab_name WHERE MATCH ('列名1,列名2...列名n') AGAINST('词1 词2 词3 ....

    一、概述

    MySQL全文检索是利用查询关键字和查询列内容之间的相关度进行检索,可以利用全文索引来提高匹配的速度。

    二、语法

    例如:SELECT * FROM tab_name WHERE MATCH ('列名1,列名2...列名n') AGAINST('词1 词2 词3 ... 词m');

    即:MATCH 相当于要匹配的列,而 AGAINST 就是要找的内容。

    这里的table需要是MyISAM类型的表,col1、col2 必须是char、varchar或text类型,在查询之前需要在 col1 和 col2 上分别建立全文索引(FULLTEXT索引)。

    三、检索方式

    1、自然语言检索: IN NATURAL LANGUAGE MODE

    2、布尔检索: IN BOOLEAN MODE

    剔除一半匹配行以上都有的词,譬如说,每个行都有this这个字的话,那用this去查时,会找不到任何结果,这在记录条数特别多时很有用,原因是数据库认为把所有行都找出来是没有意义的,这时,this几乎被当作是stopword(中断词);但是若只有两行记录时,是啥鬼也查不出来的,因为每个字都出现50%(或以上),要避免这种状况,请用IN BOOLEAN MODE。

    IN BOOLEAN MODE的特色:

    ·不剔除50%以上符合的row。

    ·不自动以相关性反向排序。

    ·可以对没有FULLTEXT index的字段进行搜寻,但会非常慢。

    ·限制最长与最短的字符串。

    ·套用Stopwords。

    搜索语法规则:

    +   一定要有(不含有该关键词的数据条均被忽略)。

    -   不可以有(排除指定关键词,含有该关键词的均被忽略)。

    >   提高该条匹配数据的权重值。

    ~   将其相关性由正转负,表示拥有该字会降低相关性(但不像 - 将之排除),只是排在较后面权重值降低。

    *   万用字,不像其他语法放在前面,这个要接在字符串后面。

    " " 用双引号将一段句子包起来表示要完全相符,不可拆字。

    - + 表示AND,即必须包含。- 表示NOT,即必须不包含。即:返回记录必需包含 apple,且不能包含 banner。

    SELECT * FROM articles WHERE MATCH (title,content) AGAINST ('+apple -banana' IN BOOLEAN MODE);

    -- apple和banana之间是空格,空格表示OR。即:返回记录至少包含apple、banana中的一个。

    SELECT * FROM articles WHERE MATCH (title,content) AGAINST ('apple banana' IN BOOLEAN MODE);

    -- 返回记录必须包含apple,同时banana可包含也可不包含,若包含的话会获得更高的权重。

    SELECT * FROM articles WHERE MATCH (title,content) AGAINST ('+apple banana' IN BOOLEAN MODE);

    -- ~ 是我们熟悉的异或运算符。返回记录必须包含apple,若也包含了banana会降低权重。

    -- 但是它没有 +apple -banana 严格,因为后者如果包含banana压根就不返回。

    SELECT * FROM articles WHERE MATCH (title,content) AGAINST ('+apple ~banana' IN BOOLEAN MODE);

    -- 返回必须同时包含“apple banana”或者必须同时包含“apple orange”的记录。

    -- 若同时包含“apple banana”和“apple orange”的记录,则“apple banana”的权重高于“apple orange”的权重。

    SELECT * FROM articles WHERE MATCH (title,content) AGAINST ('+apple +(>banana

    3、查询扩展检索: WITH QUERY EXPANSION

    四、MySQL全文检索的条件限制

    1、在MySQL5.6以下,只有MyISAM表支持全文检索。在MySQL5.6以上Innodb引擎表也提供支持全文检索。

    2、相应字段建立FULLTEXT索引

    五、与全文检索相关的系统变量:

    ft_min_word_len = 全文检索的最小许可字符(默认4,通过 SHOW VARIABLES LIKE 'ft_min_word_len' 可查看),中文通常是两个字就是一个词,所以做中文的话需要修改这个值为2最好。

    六、总结事项

    1、预设搜寻是不分大小写,若要分大小写,columne 的 character set要从utf8改成utf8_bin。

    2、预设 MATCH...AGAINST 是以相关性排序,由高到低。

    3、MATCH(title, content)里的字段必须和FULLTEXT(title, content)里的字段一模一样。

    如果只要单查title或content一个字段,那得另外再建一个 FULLTEXT(title) 或 FULLTEXT(content),也因为如此,MATCH()的字段一定不能跨table,但是另外两种搜寻方式好像可以。

    4、MySQL不支持中文全文索引,原因很简单:与英文不同,中文的文字是连着一起写的,中间没有MySQL能找到分词的地方,截至目前MySQL5.6版本是如此,但是有变通的办法,就是将整句的中文分词,并按urlencode、区位码、base64、拼音等进行编码使之以“字母+数字”的方式存储于数据库中。

    七、实验部分

    ◆ 步骤1 配置my.ini,在my.ini末尾添加如下:

    # 修改全文检索的最小许可字符为2个字符或汉字 ft_min_word_len = 2

    完成后“重启 MySQL 服务”,并用 SHOW VARIABLES LIKE 'ft_min_word_len' 查询下是否得到了正确的结果值为2.

    步骤1 创建数据表

    create table if not exists `zzx_articles` (

    `id` int(10) unsigned NOT NULL auto_increment,

    `title` char(254) default NULL COMMENT '标题',

    `content` text COMMENT '内容',

    `author` char(60) default NULL COMMENT '作者',

    `title_fc` char(254) default NULL COMMENT '标题的分词',

    `content_fc` text COMMENT '内容的分词',

    PRIMARY KEY (`id`),

    FULLTEXT KEY `zzx_title_fc` (`title_fc`),/**建立全文索引*/

    FULLTEXT KEY `zzx_content_fc` (`content_fc`),/**建立全文索引*/

    FULLTEXT KEY `zzx_title_con_fc` (`title_fc`,`content_fc`)/**建立全文索引*/

    ) ENGINE=MyISAM DEFAULT CHARSET=utf8;

    步骤2 插入测试数据

    INSERT INTO `zzx_articles` (title_fc,content_fc) VALUES

    ('MySQL Tutorial Linux red','DBMS stands for DataBase ok'),

    ('How To Use MySQL Well','After you went through blue'),

    ('Optimizing MySQL ok','In this tutorial we will optimizing'),

    ('MySQL vs this YourSQL blue red','1. Never run mysqld as root red'),

    ('MySQL Tricks blue','In the following database'),

    ('MySQL Security','When configured properly, MySQL'),

    ('中华','中华人民共和国 '),

    ('中华情 和谐','上海 和谐'),

    ('污染之都','你好 我是 北京 人'),

    ('北京精神','创新 爱国 包容 厚颜')

    步骤3 搜索语法规则、排序 实验

    说明:匹配语句 MATCH (col1,col2,...) AGAINST (expr [search_modifier]) 匹配完成后,会返回此条数据的权重值(权重值1 ≈ 各个词的匹配结果权重值之和),我们利用此权重值“由高到低”排序可优化查询结果

    ▶ 实验1:只对 title_fc 索引字段做全文检索,并显示每条数据的权重值

    SELECT *,MATCH (title_fc) AGAINST ('optimizing ok red blue') as title_score

    FROM zzx_articles

    WHERE MATCH (title_fc) AGAINST ('optimizing ok red blue' IN BOOLEAN MODE) order by title_score DESC

    结果如下图:

    总结:

    1.当没有加 + - 这样的过滤符号时,这些关键词是“或(or)”的关系,即:要么匹配optimizing,要么匹配ok,要么匹配red,要么匹配blue。

    2.通过上面实验,发现当某条数据有多个关键词匹配时(如:red blue),此条数据的权重值会略高:此条数据权重值 ≈ optimizing权重值 + ok权重值 + red权重值 + blue权重值理论上来说,当一条数据能匹配上的关键词越多,则此条数据的权重值越高,排名越靠前。

    ▶ 实验2:过滤条件:必须包含"red"关键词

    SELECT *,MATCH (title_fc) AGAINST ('optimizing ok red') as title_score

    FROM zzx_articles

    WHERE MATCH (title_fc) AGAINST ('optimizing ok +red' IN BOOLEAN MODE) order by title_score DESC

    总结:使用了过滤符号 + ,表示查询结果中,任一条数据都必须包含"red"这个词,不包含"red"这个词的行均被忽略。

    ▶ 实验3:过滤条件:必须包含"red"关键词,如果匹配到的行中还含有"blue"关键词,则会对此条数据增加权重:

    SELECT *,MATCH (title_fc) AGAINST ('optimizing ok red blue') as title_score

    FROM zzx_articles

    WHERE MATCH (title_fc) AGAINST ('optimizing ok +red blue' IN BOOLEAN MODE) order by title_score DESC

    或者写法:

    SELECT *,MATCH (title_fc) AGAINST ('optimizing ok red >blue') as title_score

    FROM zzx_articles

    WHERE MATCH (title_fc) AGAINST ('optimizing ok +red >blue' IN BOOLEAN MODE) order by title_score DESC

    总结:与实验2比较,当包含了red的行中,若也包含blue关键词,权重确实增加了(如:id=4这条)。

    ▶ 实验4:过滤条件:必须包含"red"关键词,并且不能包含"blue"关键词

    SELECT *,MATCH (title_fc) AGAINST ('optimizing ok red blue') as title_score

    FROM zzx_articles

    WHERE MATCH (title_fc) AGAINST ('optimizing ok +red -blue' IN BOOLEAN MODE) order by title_score DESC

    总结:可见 + - 这两个符号是表示“并且(and)”的意思,即:必须包含red关键词 and 不能包含blue关键词。

    ▶ 实验5:过滤条件:必须包含"red"关键词,如果匹配到的行中还包含"blue"关键词则降低此条数据权重

    SELECT *,MATCH (title_fc) AGAINST ('optimizing ok +red ~blue') as title_score

    FROM zzx_articles

    WHERE MATCH (title_fc) AGAINST ('optimizing ok +red ~blue' IN BOOLEAN MODE) order by title_score DESC

    总结:这个实验没有看到明显效果,但 ~ 过滤符确实是降低此权重符

    ▶ 实验6:过滤条件:匹配包含单词“red”和“Linux” 的行,或包含“red” 和“blue”的行(无先后顺序)然而包含 “apple Linux”的行较包含“apple blue”的行有更高的权重值。

    SELECT *,MATCH (title_fc) AGAINST ('+red +(>Linux

    FROM zzx_articles

    WHERE MATCH (title_fc) AGAINST ('+red +(>Linux

    ▶ 实验7:过滤条件:匹配关键词以 re 开头,或以 bl 开头的数据行

    SELECT *,MATCH (title_fc) AGAINST ('re* bl*') as title_score

    FROM zzx_articles

    WHERE MATCH (title_fc) AGAINST ('re* bl*' IN BOOLEAN MODE) order by title_score DESC

    总结:注意 * 是写在后面哦,此时相当于 like 模糊匹配,没有权重值了

    ▶ 实验8:过滤条件:匹配查找字符串“To Use MySQL”关键词

    SELECT *,MATCH (title_fc) AGAINST ('"To Use MySQL"') as title_score

    FROM zzx_articles

    WHERE MATCH (title_fc) AGAINST ('"To Use MySQL"' IN BOOLEAN MODE) order by title_score DESC

    总结:此时是把双引号内的的字符串看成一个关键词,若不用双引号则是将 To Use MySQL 三个关键词去分别匹配,两者有区别;

    ▶ 实验9:在实验1基础上,将blue的权重值忽视不要(注意与实验1比较)

    SELECT *,MATCH (title_fc) AGAINST ('optimizing ok red') as title_score

    FROM zzx_articles

    WHERE MATCH (title_fc) AGAINST ('optimizing ok red blue' IN BOOLEAN MODE) order by title_score DESC

    总结:在实验1的基础上,此时去除select字段条件里的blue关键词,但在where里去仍保留blue关键词。我的本意是想正常匹配“optimizing ok red blue”这几个关键词,但不想得到blue的权重值(忽视blue的权重值)。

    查询的结果是含有blue关键词的数据的权重值会略降低了。

    通过“降重”——忽略某些关键词权重值的方式可使部分数据权重值减小,进而影响排序。

    ▶ 实验10:在实验9的基础上,在select字段条件里增加几个red关键词,where里的关键词保持不变(注意与实验1 实验9比较)。

    SELECT *,MATCH (title_fc) AGAINST ('optimizing ok red red red') as title_score

    FROM zzx_articles

    WHERE MATCH (title_fc) AGAINST ('optimizing ok red blue' IN BOOLEAN MODE) order by title_score DESC

    总结:发现只要含有 red 关键词的数据的权重值都增加了,排序也发生了变化。说明通过“提重”——重复多次某些关键词权重值的方式可使部分数据权重值增加,进而影响排序。

    ▶ 实验11:同时对 title_fc 和 content_fc 两字段做全文检索

    SELECT *,MATCH (title_fc) AGAINST ('optimizing ok red blue') as title_score,MATCH (content_fc) AGAINST ('optimizing ok red blue') as content_score

    FROM zzx_articles

    WHERE MATCH (title_fc,content_fc) AGAINST ('optimizing ok red blue' IN BOOLEAN MODE) order by title_score DESC,content_score

    总结:通过实验发现,又成功的取到了 content_fc 字段匹配的权重值,排序方式是首要按title字段权重降序排序,次要按 content_fc 权重降序排序。另外我发现 ok 这个关键词在对“title_fc char(254)”字段匹配时得到匹配值为2.1xxxxxxx,但对“content_fc text”字段匹配时权重值去为0,这是MySQL对各英文单词权重值的给予有自己的算法,我们无权干涉。所以当我们发现有些单词的权重值为零甚至为负时,不用过于纠结,因为MySQL有自己的算法。

    关于排序,首要按 title_score 字段权重降序排序,次要按 content_score 权重降序排序,这样的排序规则看起来更科学了,但我想优秀的搜索引擎绝不至于简单如此吧,继续下面的实验:

    ▶ 实验12:进一步优化 排序规则看一个SQL语句原型,查询“字段1,字段2”两字段,同时将每条数据的“字段1”与“字段2”的求和作为“字段3”字段:

    select 字段1,字段2,字段1 + 字段2 as 字段3

    from 表名

    where .....

    下面将 title_fc 和 content_fc 两权重值求和,放入新字段 score1 中,并按 score1 首要排序,title_score 次之,content_score再次之:

    SELECT *,MATCH (title_fc) AGAINST ('optimizing ok red blue') as title_score,MATCH (content_fc) AGAINST ('optimizing ok red blue') as content_score,MATCH (title_fc) AGAINST ('optimizing ok red blue') + MATCH (content_fc) AGAINST ('optimizing ok red blue') as score1

    FROM zzx_articles

    WHERE MATCH (title_fc,content_fc) AGAINST ('optimizing ok red blue' IN BOOLEAN MODE) order by score1 DESC,title_scort

    总结:相对而言,如果 title_fc 和 content_fc 都匹配上了,应给予靠前的排名吧。所以首要按其 title_fc 和 content_fc 两权重值之和排名,次要再考虑 title_fc、content_fc 排序。

    ▶ 实验13:另一个角度看排序看一个SQL语句原型,如果性别字段值为“1”显示“男”否则显示“女”

    select *,IF(sex=1,"男","女") as ssva from 表名 where id = 1

    我的新排序思路:如果 title_fc 和 content_fc 同时匹配上的行做首要排序,然后对只匹配上 title_fc 的做次要排序,只匹配上 content_fc 的再次要排序。 (对于实验5的排序不科学之处在于:如果有一个对content_fc关键词的匹配权重很高,导致了求和后 score1 的值也高,但对title_fc的匹配权重去为0,由于score1值高却排到了前面这不一定科学吧?)

    SELECT *,MATCH (title_fc) AGAINST ('optimizing ok red blue') as title_score,MATCH (content_fc) AGAINST ('optimizing ok red blue') as content_score,IF(MATCH (title_fc) AGAINST ('optimizing ok red blue') > 0 AND MATCH (content_fc) AGAINST ('optimizing ok red blue') > 0,1,0) as score1

    FROM zzx_articles

    WHERE MATCH (title_fc,content_fc) AGAINST ('optimizing ok red blue' IN BOOLEAN MODE) order by score1 DESC,title_score

    总结:如果 title_fc 和 content_fc 都匹配上了,做为优先排序理所当然,但也应考虑局部权重值过高的问题哦。

    ▶ 实验14:优化实验13,可支持更复杂的条件排序看一个SQL语句原型,CASE WHEN THEN END 结构:

    CASE

    WHEN THEN

    WHEN THEN

    ...

    WHEN THEN

    ELSE

    END

    有一表查询:大于或等于80表示显示为“优秀”,大于或等于60显示为“及格”,小于60分显示为“不及格”。

    select (CASE WHEN 语文>=80 THEN '优秀' WHEN 语文>=60 THEN '及格' ELSE '不及格' END) as 语文,

    (CASE WHEN 数学>=80 THEN '优秀' WHEN 数学>=60 THEN '及格' ELSE '不及格' END) as 数学,

    (CASE WHEN 英语>=80 THEN '优秀' WHEN 英语>=60 THEN '及格' ELSE '不及格' END) as 英语

    from table_name

    # 实例测试一下

    select *,(CASE WHEN id<8 THEN '5' WHEN id=8 THEN '4' ELSE '0' END) as newfield

    from zzx_articles

    where id>5

    我的新排序思路:如果 title_fc 和 content_fc 的权重值“同时大于0且相等”为首要排序,“同时大于0且不相等”的为次要排序,“title_fc 大于0的再次要排序”,如果用 IF() 貌似不好实现,看下面语句:

    SELECT *,MATCH (title_fc) AGAINST ('optimizing ok red blue') as title_score,MATCH (content_fc) AGAINST ('optimizing ok red blue') as content_score,

    (CASE WHEN MATCH (title_fc) AGAINST ('optimizing ok red blue') > 0 AND MATCH (title_fc) AGAINST ('optimizing ok red blue') = MATCH (content_fc) AGAINST ('optimizing ok red blue') THEN '3' WHEN MATCH (title_fc) AGAINST ('optimizing ok red blue') > 0 AND MATCH (title_fc) AGAINST ('optimizing ok red blue') <> MATCH (content_fc) AGAINST ('optimizing ok red blue') THEN '2' WHEN MATCH (title_fc) AGAINST ('optimizing ok red blue') > 0 THEN '1' ELSE '0' END) AS score1

    FROM zzx_articles

    WHERE MATCH (title_fc,content_fc) AGAINST ('optimizing ok red blue' IN BOOLEAN MODE) order by score1 DESC,title_score

    总结:本实验的排序未必合乎科学,但引出一个更复杂规则的排序方式、角度,多种排序结合使用才能做出更合理的排序,才能使你的搜索引擎更加智能。抛砖引玉,或许你有更好的排序,请也分享给我。

    ▶ 实验15:中文全文检索

    MySQL不支持中文全文检索,因为中文一句话是连着写的,不像英文单词间有空格分隔。解决办法就是中文分词(关于中文分词请参阅其它文章),如果你的MySQL是安装在Windows平台上的,可以不用转码直接存储中文就可以使用全文索引,如本例。但是如果你的MySQL是安装在Linux上的则需要进行转编码(urlencode / base64_encode / json_encode / 区位 / 拼音)等方案,具体方案参看其它博文。

    SELECT *,MATCH (title_fc) AGAINST ('中华 北京 和谐 security') as title_score,MATCH (content_fc) AGAINST ('中华 北京 和谐 security') as content_score,(case when MATCH (title_fc) AGAINST ('中华 北京 和谐 security') > 0 and MATCH (content_fc) AGAINST ('中华 北京 和谐 security') > 0 then '5' when MATCH (title_fc) AGAINST ('中华 北京 和谐 security') > 0 and MATCH (content_fc) AGAINST ('中华 北京 和谐 security') = 0 then '4' else '0' end) as score1

    FROM zzx_articles

    WHERE MATCH (title_fc,content_fc) AGAINST ('中华 北京 和谐 security' IN BOOLEAN MODE) order by score1 DESC,title_score DESC,content_score DESC

    所有文章都只做学习记录,不做任何商业用途已经技术分享.

    展开全文
  • 现在的互联网上,很多网站都提供了全文搜索功能,浏览者可以通过输入关键字或者是短语来搜索特定的资料。在PHP+MySQL构架的网站中,通常的做法是通过SELECT查询的Like语句来进行搜索,这一办法存在搜索不够精确、...
  • 需求:使用postgresql13版本测试中文全文检索功能 安装postgresql13数据库 我这里是使用的docker容器安装测试的 1、创建一个centos7镜像容器 docker run -di --name postgres13 --privileged=true -p 5432:5432 ...
  • MySQL中文全文检索demoSQL 一、概述 MySQL全文检索是利用查询关键字和查询列内容之间的相关度进行检索,可以利用全文索引来提高匹配的速度。 二、语法 MATCH (col1,col2,...) AGAINST (expr [search_modifier]) ...
  • 从MySQL 5.7.6开始,MySQL内置了ngram全文解析器,用来支持中文、日文、韩文分词。 本文使用的MySQL 版本是 5.7.19,InnoDB数据库引擎并配合宝塔linux使用,全文检索适用于小型网站来代替elasticsearch和shirongram...
  • 前端检索,在es里查询,返回高亮文本和结果列表,点击定位到文档打开。 es里安装ik插件,用head和postman或curl进行调试。 因为首次使用postman,es总是返回说缺少body……错误。解决办法是勾选上head里的length...
  • 目前的中文检索查询方案基于数据库的模糊匹配(运行时字符串查找,查询速度比较慢)专有的全文检索引擎(sphinx, lucene等)我曾经遇到一个项目,数据量在百万级别,不需要高级的全文检索方式(没有复杂的匹配需求,没有...
  • mysql到版本3.23.23时,开始支持全文检索,通过语句SELECT ... FROM ... MATCH(...) AGAINST(...) 来在整个表中检索是否有匹配的,全文索引是一个定义为fulltext的类型索引,应用在myisam表中。值得一提的是对于一个...
  • MySql中文全文检索的一种实现方案在数据库中查找包含某一个关键词的内容,用SQL语句的like写起来非常简单。但是,在实际应用中,like的效率非常低,为了能满足在有大量数据的情况下快速查找的需求,我们需要对数据...
  • MongoDB 全文检索

    2020-12-19 08:39:50
    MongoDB 全文检索全文检索对每一个词建立一个索引,指明该词在文章中出现的次数和位置,当用户查询时,检索程序就根据事先建立的索引进行查找,并将查找的结果反馈给用户的检索方式。这个过程类似于通过字典中的检索...
  • sphinx(开源全文检索引擎)Coreseek(开源的中文全文检索引擎)coreseek是一个针对于中文检索方案的一种全文检索技术,基于sphinx开发的。至于好处,简单说就是迅速和高效,尤其是在当今科技迅速发展的前提下,我们要在...
  • 分布式全文检索服务器 --Elasticsearch(1)写在前面Elaticsearch, 简称为 es,es 是一个开源的高扩展的分布式全文检索引擎, 它可以近乎实时的存储, 检索数据; 本身扩展性很好, 可以扩展到上百台服务器, 处理 PB 级别的...
  • 展开全部全文检索在MySQL里面很早就支持了,只不过一直以来只支持英文。缘由是他从来32313133353236313431303231363533e...这不,从MySQL5.7开始,MySQL内置了ngram全文检索插件,用来支持中文分词,并且对MyISAM和...
  • 在5.6版本中,InnoDB加入了对全文索引的支持,但是不支持中文全文索引, 在5.7.6版本,MySQL内置了ngram全文解析器,用来支持亚洲语种的分词, 在使用前请确认自己的mysql版本, 可以使用 select version() 查看mysql的...
  • 本文写于 2021/8/18日 系统: ubuntu0.20.04.1 psql版本: psql (PostgreSQL) 12.8 (Ubuntu 12.8-0ubuntu0.20.04.1) 1. 安装 SCWS ...cd scws-1.2.3 ; ./configure ; make install 2. 下载 zhparser 源码 ...
  • 自然语言全文检索缺省或者modifier被设置为in natural language mode,都是进行自然语言检索。对于表中的每一行,match()都会返回一个关联值。mysql> CREATE TABLE articles (-> id INT UNSIGNED AUTO_...
  • CoreSeek是基于Sphinx的中文的分词和全文检索软件。本文是在MAC OS X系统下安装和调试CoreSeek。安装过程中报错如果是警告warning则忽略,如果是错误error,则必须要处理。CoreSeek是支持三种数据来源的,一种是...
  • 由于MYSQL仅支持英文的全文索引FULLTEXT,不支持中文,因为中文不能像英文那样通过空格来准确的判断单词,而需要通过语义来判断,这就需要我们对中文进行切词。但是我们可以通过另一种方式来曲线解决这一问题。项目...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 125,569
精华内容 50,227
关键字:

中文全文检索