MySQL Crash Course #12# Chapter 18 Full-Text Searching

來源:互聯網
上載者:User

標籤:name   不包含   round   port   nal   並且   ras   imp   mysql 5.6   

INDEX

   由於效能、智能結果等多方面原因,在搜尋文本時,全文檢索搜尋一般要優於萬用字元和Regex,前者為指定列建立索引,以便快速找到對應行,並且將結果集智能排序。啟用查詢擴充可以讓我們得到未必包含關鍵字的相關行,啟用布爾模式可以讓我們指定搜尋內容不應包含的單詞、各個關鍵詞的權重等。

  全文索引使用說明。

  不要在匯入資料前進行全文索引。

WARNING

不是所有資料庫引擎都支援全文檢索搜尋。MyISAM 支援全文索引,InnoDB 不支援全文索引。

PS. 據說 MySQL 5.6 以上版本的 InnoDB 支援全文索引,文法格式和 MyISAM 的全文索引類似。

Understanding Full-Text Searching

萬用字元和Regex都很強大,但是它們有幾個很嚴重的缺點:

  • 效能:萬用字元和Regex總是和表中的每一行匹配,因此當行數增加時這兩種匹配方式非常耗時。
  • 精確控制:萬用字元和Regex很難精確控制匹配什麼不匹配什麼。
  • 智能結果:例如說,不論欄位內容中有一個匹配還是多個匹配,萬用字元和Regex都一視同仁的返回該行;如果欄位內容不包含匹配,但包括相關(相近)詞不會返回該行。

上述的缺點都可以通過全文索引來解決。當使用全文檢索搜尋的時候, MySQL 不需要單獨地匹配每行,而是建立單詞(在指定的列中)的索引,這樣 MySQL 就可以快速而有效地確定哪些詞匹配,哪些不匹配等等。

可以理解為 MySQL 為指定列產生了一個目錄,該目錄標註了 包含 xxx 單詞的行是第1、4、8、9行(假設),藉助這個目錄,搜尋 xxx 單詞時就可以很快找到對應行1、4、8、9了,類似於用空間換取時間。

Using Full-Text Searching
CREATE TABLE productnotes(  note_id    int           NOT NULL AUTO_INCREMENT,  prod_id    char(10)      NOT NULL,  note_date datetime       NOT NULL,  note_text  text          NULL ,  PRIMARY KEY(note_id),  FULLTEXT(note_text)) ENGINE=MyISAM;

PS. 全文索引多個欄位也是可以的! 

一旦定義了全文索引,MySQL 會自動維護這個索引,當增加記錄、刪除記錄,索引會相應的變化

Don‘t Use FULLTEXT When Importing Data

Updating indexes takes timenot a lot of time, but time nonetheless. If you are importing data into a new table, you should not enable FULLTEXT indexing at that time. Rather, first import all of the data, and then modify the table to define FULLTEXT. This makes for a much faster data import (and the total time needed to index all data will be less than the sum of the time needed to index each row individually).

Performing Full-Text Searches
mysql> SELECT note_text    -> FROM productnotes    -> WHERE Match(note_text) Against(‘rabbit‘);+----------------------------------------------------------------------------------------------------------------------+| note_text                                                                                                            |+----------------------------------------------------------------------------------------------------------------------+| Customer complaint: rabbit has been able to detect trap, food apparently less effective now.                         || Quantity varies, sold by the sack load.All guaranteed to be bright and orange, and suitable for use as rabbit bait. |+----------------------------------------------------------------------------------------------------------------------+2 rows in set (0.00 sec)

Match(colunm_name必須和定義為 FULLTEXT的列一致) 和 Against(‘xxx‘) ,記住這兩個函數!另外,搜尋是大小寫不敏感的!

事實上,利用萬用字元也可以很方便地達到上面的效果,不過效能和結果都會有不同:

mysql> SELECT note_text    -> FROM productnotes    -> WHERE note_text LIKE ‘%rabbit%‘;+----------------------------------------------------------------------------------------------------------------------+| note_text                                                                                                            |+----------------------------------------------------------------------------------------------------------------------+| Quantity varies, sold by the sack load.All guaranteed to be bright and orange, and suitable for use as rabbit bait. || Customer complaint: rabbit has been able to detect trap, food apparently less effective now.                         |+----------------------------------------------------------------------------------------------------------------------+2 rows in set (0.00 sec)

我們很震驚地發現,雖然行數是沒錯,不過順序卻不一致 。 。 。

這是因為 全文檢索搜尋有一個重要特性:結果排名(the ranking of results),排名高的優先返回。查看列的排名:

SELECT note_text,       Match(note_text) Against(‘rabbit‘) AS rankFROM productnotes;

rank 越高的排名越前,這個與關鍵字出現與否、出現在前面還是後面等因素有關。

Using Query Expansion

When query expansion is used, MySQL makes two passes through the data and indexes to perform your search:

  • First, a basic full-text search is performed to find all rows that match the search criteria.

  • Next, MySQL examines those matched rows and selects all useful words (we‘ll explain how MySQL figures out what is useful and what is not shortly).

  • Then, MySQL performs the full-text search again, this time using not just the original criteria, but also all of the useful words.

Using query expansion you can therefore find results that might be relevant, even if they don‘t contain the exact words for which you were looking.

mysql> SELECT note_text    -> FROM productnotes    -> WHERE Match(note_text) Against(‘rabbit‘ WITH QUERY EXPANSION);+----------------------------------------------------------------------------------------------------------------------------------------------------------+| note_text                                                                                                                                                |+----------------------------------------------------------------------------------------------------------------------------------------------------------+| Quantity varies, sold by the sack load.All guaranteed to be bright and orange, and suitable for use as rabbit bait.                                     || Customer complaint: rabbit has been able to detect trap, food apparently less effective now.                                                             || Customer complaint:Circular hole in safe floor can apparently be easily cut with handsaw.                                                               || Customer complaint:Sticks not individually wrapped, too easy to mistakenly detonate all at once.Recommend individual wrapping.                         || Customer complaint:Not heavy enough to generate flying stars around head of victim. If being purchased for dropping, recommend ANV02 or ANV03 instead.  || Multiple customer returns, anvils failing to drop fast enough or falling backwards on purchaser. Recommend that customer considers using heavier anvils. |+----------------------------------------------------------------------------------------------------------------------------------------------------------+6 rows in set (0.00 sec)
Boolean Text Searches
SELECT note_textFROM productnotesWHERE Match(note_text) Against(‘+rabbit +bait"‘ IN BOOLEAN MODE);

更多操作參見原書第 18 章,通過各種符號來指明關鍵詞優先順序、包含什麼單詞、排除什麼單詞等。

Full-Text Search Usage Notes

重要的說明:

  1. MySQL 不會給短單詞建立索引,短單詞預設定義為三個字母以內的。
  2. MySQL 有一個內建的停用詞列表,它的下場和短單詞一樣,當然這個也是可以手動修改的,具體方法可以搜尋資料、查查文檔。
  3. 許多單詞出現頻繁,以至於搜尋它們將毫無用處(返回的結果太多)。 因此,MySQL授予50%的規則,一個單詞出現在50%或更多的行中,它被視為一個停用詞並被有效地忽略。 (50%的規則不用於IN BOOLEAN模式)。
  4. 如果表中的行少於三行(也就是兩行或者兩行以下,因為每個但凡出現的單詞的出現次數總是至少為行數的50%),全文檢索搜尋不返回任何結果。
  5. 單詞內的單引號會被忽略,例如 don‘t 的索引為 dont
  6. 沒有單詞分隔字元(包括日語和中文)的語言將不會正確返回全文結果。 

那麼如何?中文分詞&全文索引呢?待更新

MySQL Crash Course #12# Chapter 18 Full-Text Searching

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.