SQL Server 全文搜索功能介绍

SQL Server 的全文搜索(Full-Text Search)是基于分词的文本检索功能,依赖于全文索引。全文索引不同于传统的平衡树(B-Tree)索引和列存储索引,它是由数据表构成的,称作倒转索引(Invert Index),存储分词和行的唯一键的映射关系。倒转索引是在创建全文索引或更新全文索引时,由SQL Server自动创建和维护的。全文索引主要包含三种分析器:分词器(Word Breaker)、词干分析器(stemmer)和同义词分析器。全文索引中存储的数据是分词及其位置等信息,分词是基于特定语言的语法规则,按照特定的符号寻找词语的边界,把文本分解为“单词”,每一个单词叫做一个分词(term);全文索引有时会提取分词的词干,把词干的多种派生形式存储为单一词干,这个过程叫做提取词干;根据用户提供的自定义同义词列表,把相关的单词转换为同义词,这个过程叫做提取同义词。

生成全文索引是把用户表中的文本数据进行分词(Word breaker)和提取词干(Stemmer),并转换同义词(Thesaurus),过滤掉分词中的停用词(Stopword),最后把处理之后的数据存储到全文索引中。把数据存储到全文数据的过程叫做填充(Populate)或爬虫(Crawl)进程,全文索引的更新方式可以手动填充,自动填充,或增量填充。

一,创建全文目录和唯一索引

创建全文索引之前,必须创建全文目录(Full-Text Catalog),全文目录用于组织全文索引,是全文索引的容器。每一个全文索引必须属于一个全文目录。全文目录是个逻辑结构,跟数据库的架构(Schema)相同,根据全文索引的存储位置无关。

create fulltext catalog catalog_test
as default;

为了创建全文索引,基础表上必须存在一个唯一的(unique)、单列的(single-column)、非空的(non-nullable)的索引,全文引擎使用该索引把基础表上的每行数据映射唯一索引键上,倒转索引存储的就是该索引键和分词之间的映射关系。

create unique index uidx_dbLogID
on [dbo].[DatabaseLog]
([DatabaseLogID]);

二,创建全文索引

每个表只能创建一个全文索引,创建全文索引时,必须考虑全文索引存储的文件组,全文索引关联的停用词列表,全文索引的更新方式,以及跟文本关联的语言,全文索引列必须是文本字段,例如:

create fulltext index
on [dbo].[DatabaseLog]
(
[tsql] language 1033
)
key index ui_dbLogID
on (catalog_test,filegroup [primary])
with(change_tracking=off ,no population ,stoplist=system);

1,语言(language)

选项 language 是可选的,用于指定列级别的语言,该选项的值可以是语言的名称或LCID,如果没有指定language选项,那么使用SQL Server实例的默认语言。从系统视图 sys.fulltext_languages (Transact-SQL)中查看系统支持的语言及其对应的LCID 和名称。

2,全文目录(fulltext_catalog)

选项fulltext_catalog_name 用于指定全文索引的分组,

3,文件组(filegroup)

选项 filegroup filegroup_name 用于指定全文索引存储的文件组,如果没有指定文件组,那么全文索引和基础表存储在相同的文件组中。由于更新全文索引是IO密集型操作,因此,为了更快的更新全文索引,最好把全文索引存储在不同于基础表的的物理硬盘或文件组上,以达到最大的IO并发。

4,填充全文索引的方式

和普通的索引相同,当基础表数据更新时,全文索引必须自动更新,这是系统默认的行为,也可以配置手动更新全文索引,或者间隔特定的时间点自动更新全文索引。

选项CHANGE_TRACKING 用于指定跟全文索引列相关的数据更新(Update,Delete,或Insert)是否需要同步到全文索引,
•CHANGE_TRACKING = MANUAL :手动更新
•CHANGE_TRACKING =AUTO:自动更新,默认设置,当基础表数据变化时,全文索引自动更新,
•CHANGE_TRACKING =OFF , NO POPULATION:不更新,指定选项NO POPULATION,表明在创建全文索引之后,SQL Server不会更新(populate)全文索引;如果未指定选项NO POPULATION,在创建全文索引之后,SQL Server更新全文索引。

5,停用词(STOPLIST)

停用词(StopWord)也称作噪音词,每一个全文索引都会关联一个停用词列表,默认情况下,全文索引关联的是系统停用词(system stoplist)。全文引擎把停用词从分词中删除,使全文索引不会包含停用词。

STOPLIST [ = ] { OFF | SYSTEM | stoplist_name } 

三,填充全文索引

填充全文索引也叫做爬虫(crawl)进程,或填充(Population)进程。由于创建或填充全文索引会消耗大量的系统(IO、内存)资源,因此尽量选择在系统空闲时对全文索引进行填充。在创建全文索引时,通过指定选项 CHANGE_TRACKING= MANUAL,或 CHANGE_TRACKING= OFF, NO POPULATION,新建的全文索引不会立即填充,用户可以选择在系统空闲时,使用 alter fulltext index 语句执行填充操作。只有填充全文索引之后,全文索引才包含基础表的分词数据。

alter fulltext index
on table_name
start { full | incremental | update } population;

更新全文索引有三种方式:

•FULL POPULATION:全部填充,从基础表中获取每一行,重新编入全文索引;
•INCREMENTAL POPULATION:增量填充,前提是基础表中包含timestamp字段,从上一次填充之后,只把更新之后的数据编入全文索引;
•UPDATE POPULATION:更新填充,从上一次填充之后执行更新(insert、update、或delete)操作的数据行重新编入索引;

在创建全文索引时,如果指定CHANGE_TRACKING=AUTO   或   CHANGE_TRACKING=  OFF , 那么新建的全文索引会立即开始填充进程。

四,使用 contains 谓词查询全文索引

如果想要在查询中使用全文索引,通常使用CONTAINS谓词来调用全文索引,实现比LIKE关键字更复杂的文本匹配查询,而LIKE关键字是模糊匹配,不会调用全文索引。

例如,利用contains谓词执行单个分词的完全匹配查询:

select [tsql]
from [dbo].[DatabaseLog]
where contains([tsql], 'searchword', language 1033);

全文查询跟Like相比,速度更快,支持的搜索功能更复杂,使用contains谓词,不仅能够执行分词的完全匹配或分词的前缀匹配查询,还能够执行基于词根的查询,基于自定义同义词的查询,基于距离和顺序的相邻分词查询。但是,和Like 相比,contains谓词不能进行后缀匹配查询。

contains谓词返回的结果是布尔值,如果全文索引列中包含指定的关键字或查找模式(pattern),返回TRUE;否则,返回FALSE。

contains谓词支持word查询和短语查询,word是指单个分词,短语(phrase)是由多个word和间隔的空格组成的,对于短语,必须使用双引号,将多个word组成一个短语。

1,逻辑组合查询

使用and ,and not, 或 or 逻辑运算符 匹配多个word 或 多个phrase

CONTAINS(Name, '"Mountain" OR "Road" ')
CONTAINS(Name, ' Mountain OR Road ')

2,前缀查询

使用contains谓词进行前缀匹配,和like 'prefix%'功能相同,只不过contains谓词使用“*”作为通配符,“*”匹配0,1或多个字符,前缀匹配的写法是:'"prefix*"',全文索引只能执行前缀匹配。

CONTAINS(Name, ' "Chain*" ')
CONTAINS(Name, '"chain*" OR "full*"')

3,查询同义词(thesaurus)或词干(stemmer)

Stemmer(词干),例如,根据语法规程,英语的动词 根据数(单数,复数),人称,时态的不同而存在不同的变化形式,这些单词都是同源的。

CONTAINS(Description, ' FORMSOF (INFLECTIONAL, ride) ')

THESAURUS (同义词),需要导入XML进行配置,SQL Server 提供一个默认的Thesaurus file,是Empty的。如果在Thesaurus file 配置“Author”,“Writer”,“journalist” 是同义词,在使用fulltext index查询时,只要满足任意一个同义词,都匹配成功。

CONTAINS(Description, ' FORMSOF (THESAURUS, author) ')

4,距离查询

使用 near 函数,查询匹配相邻分词的数据行,near函数的定义如下,用于需要在查询模式中指定距离查询的查询模式:

NEAR ( ( { <simple_term> | <prefix_term> } [ ,…n ] ) [, <maximum_distance> ] [, <match_order> ] ) 

例如:使用Near 函数指定相邻分词的距离和匹配顺序,near((term1,term2,term3),5)表示任意两个term之间的距离不能超过5, near((term1,term2,term3),5,true),表示任意两个term的距离不能超过5,并且按照 term1,term2,term3的顺序存在于字符串中。

--regardless of the intervening distance and regardless of order
CONTAINS(column_name, 'NEAR(term1,"term3 term4")')
--searches for "AA" and "BB", in either order, within a maximum distance of five
CONTAINS(column_name, 'NEAR((AA,BB),5)')
--in the specified order with regardless of the distance
CONTAINS(column_name, 'NEAR ((Monday, Tuesday, Wednesday), MAX, TRUE)')

对于 near((term1,term2,term3),5,true),term1 和 term5之间最多存在5个term,不包括内部的搜索分词,“term2”,例如:

CONTAINS(column_name, 'NEAR((AA,BB,CC),5)')

这个查询会匹配下面的文本,注意,内部的搜索分词CC没有计算距离:

BB one two CC three four five AA

例如,在原文本中,分词bike和control的最大距离不能超过10,分词bike必须出现在分词control的前面:

CONTAINS(Comments , 'NEAR((bike,control), 10, TRUE)')

SQL Server提供的全文搜索功能,比LIKE关键字丰富,具备初级的全文搜索功能,速度快,维护简单,缺点是,全文搜索功能非常有限,在实际的开发中,可以配合开源的全文搜索引擎,例如,Solr,Elasticsearch等来开发功能更强大的全文搜索功能。

总结

以上所述是小编给大家介绍的SQL Server 全文搜索功能介绍,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,下班会及时回复大家的!

(0)

相关推荐

  • 在SQL Server 2005所有表中搜索某个指定列的方法

    有时候我们只知道列的名字,但是不知道这列数据到底在哪个表里面,那么可以用下面的办法把含有这列数据的表查找出来. 复制代码 代码如下: Select O.name objectName, C.name ColumnName from sys.columns C inner join sys.objects O ON C.object_id=O.object_id where C.name like '%ColumnName%'order by O.name, C.name 在你实际试用中,把Col

  • 在SQL Server中实现最短路径搜索的解决方法

    开始这是去年的问题了,今天在整理邮件的时候才发现这个问题,感觉顶有意思的,特记录下来. 在表RelationGraph中,有三个字段(ID,Node,RelatedNode),其中Node和RelatedNode两个字段描述两个节点的连接关系:现在要求,找出从节点"p"至节点"j",最短路径(即经过的节点最少). 图1. 解析: 了能够更好的描述表RelationGraph中字段Node和 RelatedNode的关系,我在这里特意使用一个图形来描述,如图2. 图2

  • SQLServer地址搜索性能优化

    这是一个很久以前的例子,现在在整理资料时无意发现,就拿出来再改写分享. 1.需求 1.1 基本需求: 根据输入的地址关键字,搜索出完整的地址路径,耗时要控制在几十毫秒内. 1.2 数据库地址表结构和数据: 表TBAddress 表数据 1.3 例子: e.g. 给出一个字符串如"广 大",找出地址全路径中包含有"广" 和"大"的所有地址,結果如下: 下面将通过4个方法来实现,再分析其中的性能优劣,然后选择一个比较优的方法. 2.创建表和插入数据

  • sqlserver中在指定数据库的所有表的所有列中搜索给定的值

    比如:我们导入了某个客户的资料,我们知道此客户的姓名是ZhangShan,我们想知道,在我们的业务数据库(eg:NorthWind)中,有哪些数据表的哪些字段设置了此姓名值ZhangShan,通过下面的SQL,我们就可以实现此目的,此处的SQL搜索自网上,在此处做了局部修改. 一.搜索数据是String类型 适用于搜索Text,NText,Varchar,Nvarchar,Char,NChar等类型 1.创建存储过程:My_Search_StringInGivenTable 复制代码 代码如下:

  • SQL Server 全文搜索功能介绍

    SQL Server 的全文搜索(Full-Text Search)是基于分词的文本检索功能,依赖于全文索引.全文索引不同于传统的平衡树(B-Tree)索引和列存储索引,它是由数据表构成的,称作倒转索引(Invert Index),存储分词和行的唯一键的映射关系.倒转索引是在创建全文索引或更新全文索引时,由SQL Server自动创建和维护的.全文索引主要包含三种分析器:分词器(Word Breaker).词干分析器(stemmer)和同义词分析器.全文索引中存储的数据是分词及其位置等信息,分词

  • SQL Server的全文搜索功能

    目录 一.使用SQL Server全文搜索配置 1.开启全文搜索服务: 2.开启数据库的全文索引功能: 3.创建全文索引目录: 4.创建唯一索引: 5.创建全文索引: 二.使用全文搜索 CONTAINS搜索方式 1.简单词搜索 2.前缀词搜索的方式 3.加权词搜索的方式 4.邻近词搜索的方式 FREETEXT搜索方式 CONTAINSTABLE搜索方式 1.CONTAINSTABLE基本搜索: 2.CONTAINSTABLE返回所需列: 3.CONSTAINSTABLE按符合条件排序 4.CON

  • PHP在innodb引擎下快速代建全文搜索功能简明教程【基于xunsearch】

    本文实例讲述了PHP在innodb引擎下快速代建全文搜索功能的方法.分享给大家供大家参考,具体如下: 需要准备的设备:Liunx(Centos)操作系统(只支持Linux),PHP环境. 这里介绍一个国人开发的搜索引擎开源项目-讯搜(xunsearch),它分为:索引服务器和搜索服务器. 在CentOS下面愉快的代建服务器 wget http://www.xunsearch.com/download/xunsearch-full-latest.tar.bz2 tar -xjf xunsearch

  • SQL Server实现group_concat功能的详细实例

    目录 一.实现 二.原理分析 2.1.FOR XML PATH的作用 2.2.STUFF函数 2.2.1.STUFF函数在本SQL的作用 2.2.2.STUFF函数语法 2.3.sql语分分析 2.3.1.一个简单的group by 2.3.2.在select语句后面加上子查询 2.3.3.去掉子查询结果集的第一个分隔符 总结 一.实现 #tmp表内容如下: 实现group_concat的sql语句为: Select RegionID, STUFF( ( SELECT ',' + T.c1 FR

  • Sql Server 2016新功能之Row-Level Security(值得关注)

    Sql Server 2016 有一个新功能叫 Row-Level Security ,大概意思是行版本的安全策略(原来我是个英语渣_(:з」∠)_) 直接上例子.这个功能相当通过对表添加一个函数作为过滤规则,使得拥有不同条件的用户(或者登录名) 之类的,只能获取到符合条件的数据.相对来说是提供了那么一点的便捷性,当然也增加了数据的安全性,相当于每个用户连接进来只能看到 符合规则的数据(当然,这里的用户只是一个举例.其实是可以通过编写过滤函数来实现的) 举个例子 有三个用户 Sales1 ,Sa

  • php利用scws实现mysql全文搜索功能的方法

    本文实例讲述了php利用scws实现mysql全文搜索功能的方法.分享给大家供大家参考.具体方法如下: scws这样的中文分词插件比较不错,简单的学习了一下,它包涵一些专有名称.人名.地名.数字年代等规则集合,可以直接将语句按这些规则分开成一个一个关键词,准确率在90%-95%之间,按照安装说明把scws的扩展放入php的扩展目录里,下载规则文件和词典文件,并在php配置文件中引用它们,就可以用scws进行分词了. 1) 修改 php 扩展代码以兼容支持 php 5.4.x 2) 修正 php

  • Mongodb实战之全文搜索功能

    前言 众所周知在传统的关系型数据库中,我们通常将数据结构化,通过一系列表关联.聚合来查询我们所需的结果.而在非结构化的数据中,缺少这种预定义的结构,因而如何快速查询定位到我们所需要的结果,不是一件容易的事. Mongodb作为一种NoSQL数据库,非常适合存储和管理非结构化数据,例如互联网上的各种文本数据.假如我们用Mongodb存储了很多博客文章,那么如何快速找到所有关于"nodejs"这个主题的文章呢?Mongodb内建的全文搜索可以帮助我们完成这个功能.下面话不多说了,来一起看看

  • 使用ElasticSearch6.0快速实现全文搜索功能的示例代码

    本文不涉及ElasticSearch具体原理,只记录如何快速的导入mysql中的数据进行全文检索. 工作中需要实现一个搜索功能,并且导入现有数据库数据,组长推荐用ElasticSearch实现,网上翻一通教程,都是比较古老的文章了,无奈只能自己摸索,参考ES的文档,总算是把服务搭起来了,记录下,希望有同样需求的朋友可以少走弯路,能按照这篇教程快速的搭建一个可用的ElasticSearch服务. ES的搭建 ES搭建有直接下载zip文件,也有docker容器的方式,相对来说,docker更适合我们

  • SQL Server中的游标介绍

    游标是面向行的,它会使开发人员变懒,懒得去想用面向集合的查询方式实现某些功能. 在性能上,游标会吃更多的内存,减少可用的并发,占用带宽,锁定资源,当然还有更多的代码量.用一个比喻来说明为什么游标会占用更多的资源.当你从ATM机取款的时候,是一次取1000的效率更高呢,还是10次100呢? 游标是非常邪恶的一种存在,使用游标经常会比使用面向集合的方法慢2-3倍,当游标定义在大数据量时,这个比例还会增加.如果可能,尽量使用while,子查询,临时表,函数,表变量等来替代游标,记住,游标永远只是你最后

  • SQL Server中的事务介绍

    事务全部是关于原子性的.原子性的概念是指可以把一些事情当做一个单元来看待.从数据库的角度看,它是指应全部执行或全部都不执行的一条或多条语句的最小组合.为了理解事务的概念,需要能够定义非常明确的边界.事务要有非常明确的开始和结束点.SQL Server中的每一条SELECT.INSERT.UPDATE和DELETE语句都是隐式事务的一部分.即使只发出一条语句,也会把这条语句当做一个事务-要么执行语句中的所有内容,要么什么都不执行.但是如果需要的不只是一条,可能是多条语句呢?在这种情况下,就需要有一

随机推荐