mysql全文索引 插件,如何编写MySQL全文索引插件

为了帮助大家了解布尔查询,这里摘录一段MySQL手册里的相关描述。如下:

1.      'applebanana'

寻找包含至少两个单词中的一个的行。

2.      '+apple+juice'

寻找两个单词都包含的行。

3.      '+applemacintosh'

寻找包含单词“apple”的行,若这些行也包含单词“macintosh”,则列为更高等级。

4.      '+apple-macintosh'

寻找包含单词“apple”但不包含单词 “macintosh”的行。

5.      '+apple+(>turnover

寻找包含单词“apple”和“turnover”的行,或包含“apple”和“strudel”的行 (无先后顺序),然而包含“apple turnover”的行较包含“apple strudel”的行排列等级更为高。

6.      'apple*'

寻找包含“apple”、“apples”、“applesauce”或“applet”的行。

7.      '"somewords"'

寻找包含原短语“some words”的行 (例如,包含“some words of wisdom”的行,而非包含 “some noisewords”的行)。注意包围词组的‘"’符号是界定短语的操作符字符。它们不是包围搜索字符串本身的引号。

full text plugin的工作流程如下图所示:

9a0922ea51aa17ac5a80706bde973cc4.gif

下面,我们通过一个简单的例子来理解创建Full Text Plugin的过程

2)示例:对内建的布尔操作符进行改进,实现AND、OR和NOT操作(摘自)

实现思路:

基本思想是通过预读取的方法,在读单词时总是向后看有没有操作符,以决定当前单词的yesno,即是否是需要匹配的单词。

?  在AND前后的word yesno= 1

?  对于foo AND NOTbar  需要向前看两个单词

?  wd1 OR wd2 ,前后的yesno = 0. 但当包含AND时,例如wd1 or wd2 and wd3,wd2的yesno = 1;

?  对于类似wd1 andwd2 or wd3 and wdb4,需要使用子表达式来分离AND和OR

?  如果没有使用操作符,例如wd1 wd2 转换为wd1 OR wd2

代码如下:

/*必要的头文件*/

#include 

#include 

#include 

#include 

/*用于辅助记录分词*/

typedefstruct{

char*start;//在字符串中的起始指针

intlen;//长度

intyesno;//是否被忽略

}WORD;

/*找到s和end间的第一个单词*/

staticchar*get_word(WORD*word,char*s,char*end)

{

word->yesno = 0;

while(s 

s++;

word->start = s;

while(s 

s++;

word->len = s - word->start;

returns;

}

staticintandor_parse(MYSQL_FTPARSER_PARAM*param)

{

/*需要解析的文档*/

char*end = param->doc + param->length;

char*s = param->doc;

WORDword, next;

MYSQL_FTPARSER_BOOLEAN_INFO bool_info =

{ FT_TOKEN_WORD, 0, 0, 0, 0, 0, 0 };

/*获取第一个单词*/

s = get_word(&next, s, end);

for(;;)

{

word = next;

/*向后看一个单词*/

s    = get_word(&next, s, end);

/*已解析完文档,返回0*/

if(word.start >= end)

return0;

/*首先判断是否为boolean mode*/

if(param->mode == MYSQL_FTPARSER_FULL_BOOLEAN_INFO)

{

/*检查下一个单词是否为AND*/

if(next.start 

if(word.yesno == 0){//当前单词之前没有AND

bool_info.yesno = 0;

bool_info.type  = FT_TOKEN_LEFT_PAREN;

/*���加子表达式开始标记*/

param->mysql_add_word(param, 0, 0,&bool_info);

/*置当前单词yesno为1,表示不可忽略*/

word.yesno = 1;

}

/*读下一个单词*/

s =get_word(&next, s, end);

/*如果下一个单词为”not”  例如,word1 and notword2*/

if(next.start

/*继续读下一个单词*/

s = get_word(&next, s , end);

/*忽略该单词*/

next.yesno  = -1;

}else

next.yesno= 1;//AND的下一个单词

}

else

if(next.start

/*获取下一个单词*/

s = get_word(&next, s, end);

bool_info.type  = FT_TOKEN_WORD;

bool_info.yesno = word.yesno;

}

/*将当前单词加入到param中*/

param->mysql_add_word(param,word.start, word.len, &bool_info);

/*if there isAND before current word and no AND after it ,need to end subexpression*/

/*如果当前词之前有AND,并且当前词之后没有AND,则结束子表达式*/

if(word.yesno && !next.yesno){

bool_info.type = FT_TOKEN_RIGHT_PAREN;

param->mysql_add_word(param, 0, 0,&bool_info);

}

}

}

/*声明插件结构体*/

staticstructst_mysql_ftparser ft_andor =

{

MYSQL_FTPARSER_INTERFACE_VERSION,

audor_parse,

NULL,/*init,SET NULL */

NULL/*deinit,SET NULL*/

};

mysql_declare_plugin(andor)

{

MYSQL_FTPARSER_PLUGIN,

&ft_andor,

"andor",

"Sergei Golubchik",

"A Full-Text AND/OR boolean parser",

PLUGIN_LICENSE_GPL,

NULL,

NULL,

0x0100,

NULL,

NULL,

NULL

}

mysql_declare_plugin_end;0b1331709591d260c1c78e86d0c51c18.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值