SQL Server 全文搜索

来源:http://www.cnblogs.com/ljhdo/archive/2017/12/15/5041605.html
-Advertisement-
Play Games

SQL Server 的全文搜索(Full-Text Search)是基於分詞的文本檢索功能,依賴於全文索引。全文索引不同於傳統的平衡樹(B-Tree)索引和列存儲索引,它是由數據表構成的,稱作倒轉索引(Invert Index),存儲分詞和行的唯一鍵的映射關係。倒轉索引是在創建全文索引或更新全文索 ...


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_TRACKINGMANUAL,或 CHANGE_TRACKINGOFF, 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等來開發功能更強大的全文搜索功能。

 

參考文檔:

Full-Text Search (SQL Server)

CONTAINS (Transact-SQL)

CREATE FULLTEXT CATALOG (Transact-SQL)

Get Started with Full-Text Search

SQLSERVER全文搜索

Improve the Performance of Full-Text Queries


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • .Net Core 將之前Web.Config中的配置遷移到了appsettings.json文件中,並使用ConfigurationBuilder來讀取這個配置文件。並可設置在配置文件變化以後,自動重新載入,這樣可不用重啟你的程式。 ...
  • 一、MVC簡介 MVC:Model-View-Controller(模型-視圖-控制器),MVC是一種軟體開發架構模式。 1、模型(Model) 模型對象是實現應用程式數據域邏輯的應用程式部件。 通常,模型對象會檢索模型狀態並將其存儲在資料庫中。 例如,Product 對象可能會從資料庫中檢索信息, ...
  • 背水一戰 Windows 10 之 控制項(自定義控制項): 自定義控制項的基礎知識,依賴屬性和附加屬性 ...
  • 1.在之前第36章里,我們學習了通過驅動的oops定位錯誤代碼行 第36章的oops代碼如下所示: 1.1那為什麼在上一章,我們用錯誤的應用程式,卻沒有列印oops,如下圖所示: 接下來,我們便來配置內核,從而列印應用程式的oops 2.首先來搜索oops里的:Unable to handle ke ...
  • 前言 使用VMware安裝虛擬機這個一般都知道,操作簡單。而本文主要講使用虛擬機的後續相關配置。並記錄使用過程中遇到的問題以及一些技巧。本篇文章以後回持續更新的。。。 安裝包准備 VM:12 Linux:CentOS 7.0 百度雲盤: 鏈接:https://pan.baidu.com/s/1geE ...
  • Win10筆記本如何禁用觸摸板呢?Win10筆記本如何設置“插入滑鼠自動禁止觸摸板功能”呢?雖然筆記本觸摸板在一定程度上可以方便我們的 操作,但是在以滑鼠和鍵盤做為重要的輸入設備的情況下,筆記本觸摸板有時由於觸摸、誤按等操作,導致造成一些不必要的後果。對此我們可以通過 以下方法實現筆記本觸摸板的禁用 ...
  • 最近突然想搭一個redis集群玩玩,因為公司的電腦同時開2個虛擬機就卡的不行,所以我就想到用Docker開啟多個redis-server來搭建。然後在網上找著找著發現,使用Docker,哪需要搭建啊,直接Docker pull一個鏡像就OK了。加上之前使用Docker,五分鐘搭建一個類似github ...
  • 會提到:“安裝程式無法與下載伺服器聯繫。請提供 Microsoft 機器學習伺服器安裝文件的位置,然後單擊“下一步”。可從以下位置下載安裝文件” 的解決方案 安裝過程和2016大體一致,機器學習這款更完善了。(其他錯誤看看往期的解決吧:http://www.cnblogs.com/dunitian/ ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...