返回1表示已安装全文组件,返回0表示未安装全文组件,返回Null表示输入无效或发生错误。
2.为数据库启用全文支持
只有为数据库启用了全文支持,才能进一步设置数据表和数据列。
这里,首先检查一下目标数据库是否已经启用了全文支持。执行下面的SQL语句:
use tianen
select Database Property("tianen","IsFulltext Enabled")
如果该数据库已经启用了全文支持,则返回1;否则返回0。
现在,tianen数据库还没有启用全文支持。执行下面的SQL语句将其启用:
use tianen
Exec sp fulltext database"enable"
3.创建全文目录
在tianen数据库中执行下面的SQL语句,创建一个名为“tianen Catalog”的全文目录作为候选的默认目录。
use tianen
Exec sp fulltext catalog"tianen Catalog","create"
这将在数据库系统表中创建有关全文目录的元数据,并在文检系统中生成空的全文目录。
可以展开企业管理器的tianen节点,单击“全文目录”可以查看到刚创建的tianenCatalog全文目录的情况。
4.注册用于全文检索的表
一个数据库可以包含多个表格,如果要对某个表执行全文检索操作,就要将其注册全文检索。
本例中,tianen数据库中只包含一个表test,将其注册全文检索的方法是执行下面的SQL语句:
use tianen
Exec sp fulltext table"test","create","tianen Catalog","PK test"
这里需要注意的是语句中的第四项,“PK test”是表格test的唯一键。可以在企业管理器中查看和修改。
5.指定用于全文检索的列
一个表格可以包含多个列,如果要对某个列执行全文检索操作,就要将其注册全文检索。本例中,test表格包含四个列,指定title和content列为支持全文检索的列。执行下面的SQL语句:
use tianen
Exec sp fulltext column"test","title","add"
Exec sp fulltext column"test","content","add"
6.激活全文索引
现在全文索引已经创建好了,但是还没有激活,所以不能用。需要将其激活,也就是在全文目录中注册表格。执行下面的SQL语句:
use tianen
Exec sp fulltext table"test","activate"
7.执行全文目录的填充
全文索引激活之后,下面需要对表格中的数据建立索引。这里面涉及数据提取、分词等操作,通过执行下面的SQL语句即可完成这个过程,实现对全文目录的完全填充(因为是第一次填充,所以用完全填充)。这个过程完成之后,就可以使用全文检索了。
use tianen
Exec sp fulltext catalog"tianen Catalog","start full"
全文目录的填充是一种一步操作,一般不会立即创建出索引。而且,创建索引所用的时间取决于表的数据量大小。具有4000000条记录的表的全文索引通常需要几个小时才能填充完成,而具有20000000条记录的表的全文索引往往要用几天才能填充完。
可以通过执行下面的语句来查看全文目录的填充进度:
use tianenselect FulltextCatalogProperty("tianen Catalog","Populate Status")如果全文目录已经填充完成,则返回0;否则返回1或更大的值,表示正处于填充阶段。
返回值为0,证明已经填充完成了。之所以这么快,是因为表格中的数据量非常少。
通常,可以用下面的SQL语句来检查全文目录的填充状态:
WHILE Fulltext Catalog Property("FT pubs","Populate Status")<>0
BEGIN
——如果全文目录正在填充,则等待30秒后再检测一次
WAITFORDELAY"0:0:30′
END
这里,为全文目录请求了完全填充,那么系统会为该目录所涉及的所有表中的所有行生成索引项。如果是为表请求完全填充,就只为该表中的所有行生成索引项。
完全填充通常发生在对数据库表第一次建立全文索引的时候,当执行了这次完全填充之后,再向数据库中添加新记录,新记录并不被建入索引。这时启动增量填充,即可将新记录建入索引,这时也可以用完全填充,但是不经济、浪费资源。执行下面的SQL语句即可启动增量填充:
use tianen
Exec sp fulltext catalog"tianen Catalog","start incremental"
4.3.3体验全文检索
现在,可以享受一下刚才的劳动成果了。
在查询分析器中输入下面的语句,选出在content字段中包含“大禹”这个词的所有记录。
use tianenselect*from test where CONTAINS(content,′"大禹"")
笔者对这个结果非常满意,这并不是因为微软可以实现全文检索(那不算什么,谁都可以做到),而是感慨,“大禹”是中国的上古英雄,微软在做分词的时候可以考虑得这么周全,可见其良苦用心。
尝试一下,在查询分析器中输入以下语句:
use tianen
select*from test whereCONTAINS(common,′"大禹"")
无法执行查询。这就是说,在指定用于全文检索的列的时候,没有被指定的列不支持全文检索。
尝试一下,在查询分析器中输入以下语句:
use tianen
select*from test where common like"%大禹%"
这是用常规的like谓词实现模糊搜索。这说明,在为数据库启用全文检索的时候,常规的检索依然有效。在这个例子中,可以发现用like搜索的速度也很快,这是因为数据表中的数据量很少。
4.4谓词和行集函数
在前面的例子中用到了CONTAINS谓词,它是用于全文检索的两个谓词之一。这一节将介绍SQL Server全文检索的两个谓词CONTAINS和FREETEXT及两个行集函数CONT-AINSTABLE和FREETEXTTABLE的用法。其中,CONTAINS最常用,所以详细讲解,其他的略讲。
4.4.1CONTAINS的用法
CONTAINS谓词用于搜索包含基于字符的数据类型的列,该列于搜索词进行模糊匹配或加权匹配。可以指定的搜索条件包括:
某一列含有某个词;
某一列同时含有某几个词;
某一列含有某个词同时不含有另一个词;
某一列不含有某个词;
某一列含有某个词或另一个词。
不只可以对一列进行搜索,也可以同时对几列进行搜索。
具体的例子如下。
(1)搜索在“content”列中含有“大禹”的记录语句如下:
use tianen
select*from test where CONTAINS(content,′"大禹"")
这里要注意格式,被检索的列在括号的前面,之后是逗号,然后是检索条件,检索条件用半角双引号括起来,外面是半角的单引号。
(2)搜索在“content”列中同时含有“大禹”和“涂山氏”的记录语句如下:
use tianen
select*from test where CONTAINS(content,′"大禹"AND"涂山氏"")
这里使用了AND来连接两个并列的搜索条件,意思是要求被检索的列中同时含有多个检索词。
使用AND可以连接多个并列的搜索条件,例如:
use tianen
select*from test where CONTAINS(content,′"大禹"AND"鲧"AND"水"")
这里使用了AND来连接三个并列的搜索条件,意思是要求被检索的列中同时含有三个检索词:“大禹”,“鲧”,“水”。
(3)搜索在“content”列中含有“大禹”却不含有“涂山氏”的记录语句如下:
use tianen
select*from test where CONTAINS(content,′("大禹")AND NOT("涂山氏")")
这里使用了AND NOT符号来连接两个搜索条件,表示要求被检索的列中含有前面的检索词,而不含有AND NOT后面括号中的词。
(4)搜索在“content”列中不含有“涂山氏”的记录语句如下:
use tianen
select*from test where not CONTAINS(content,′"涂山氏"")
(5)搜索在“content”列中含有“大禹”或“妹喜”的记录语句如下:
use tianen
select*from test where CONTAINS(content,′("大禹")OR("妹喜")")
这里使用了OR符号来连接多个条件,表示“或”的关系。
(6)搜索在“content”列或“title”列中含有“大禹”的记录语句如下:
use tianen
select*from test where CONTAINS(title,′"大禹"")or CONTAINS(content,′"大禹"")
在这里,如果之前对数据表的common列也注册了全文检索,那么想要搜索在“content”列或“title”列或“commont”列中含有“大禹”的记录,就需要用下面的语句:
use tianen
select*from test where CONTAINS(title,′"大禹"")or CONTAINS(content,′"大禹"")or CONTAINS(common,′"大禹"")
这样一来,CONTAINS谓词数量增多,会严重影响搜索的效率。一个常用的解决方案是用“*”来代替列名,“*”代表数据表被注册全文检索的每个列。运行的结果相当于把多个CONTAINS子句并列起来,但效率要高很多。如下面的语句所示:
use tianen
select*from test where CONTAINS(*,′"大禹"")
(7)常规检索谓词的应用
在使用全文检索谓词的时候,原有的常规检索谓词依然有效,如以下语句所示:
use tianen
select*from test where CONTAINS(title,′"大禹"")and common like"%音乐%"
(8)复杂的检索
综合使用AND,AND NOT和OR运算符,以及常规的检索谓词,可以构造出复杂的SQL语句,读者可以根据需要自行解决。这里仅举一例,如下所示:
use tianen
select top2* from test where(CONTAINS(content,′"水"")and id<4)
(9)其他用法
全文检索引擎最早是用于英文的,所以,CONTAINS谓词包含很多对英文的特殊检索功能。英语和汉语有很多不同,比如英语的单词有时态区别,get,got是一个词的不同时态。那么,如果一个人要搜索“get a cheese”,那么在文章中出现了“got a cheese”也算对。SQL Server的全文检索做到了这一点,类似的高级功能还有很多,只是对我们做中文搜索没有太大帮助,这里就不再赘述。
4.4.2FREETEXT的用法
FREETEXT谓词用于搜索包含基于字符的数据类型的列,其中的值符合在搜索条件中所指定文本的含义,但不符合表达方式。使用FREETEXT时,全文检索引擎内部将查询字符串拆分成若干个搜索词,并赋予每个词以不同的加权,然后查找匹配。
比如,在content列中检索:
FREETEXT(content,′"大禹为万民治水"")
这时,检索引擎将首先标识出如下的词语:
大禹、禹万、民、治水、水
然后,这些词语在内部结合到一个查询中,并被赋予适当的加权等级值,然后才执行实际的检索。
尝试一下,执行下面三个搜索。
搜索1:
use tianen
select*from test where content like"%大禹为万民治水%"
这里,使用常规的like搜索,搜索在列中包含“大禹为万民治水”这个词的记录,没有结果。
说明,数据库中并没有这样的记录存在。
搜索2:
use tianen
select*from test whereCONTAINS(content,′"大禹为万民治水"")
这里,使用CONTAINS搜索,调用全文索引,执行全文搜索,还是没有得到结果。这说明CONTAINS忠实地执行了我们的搜索条件。