標籤:image org 用法 技術分享 level ora 相關 資料 eve
建立全文索引(FullText index)
建立表的同時建立全文索引
FULLTEXT (name) WITH PARSER ngram
通過 alter table 的方式來添加
alter table `das`.`staff_base` add fulltext index staff_base_name(`name`) with parser ngram;
直接通過create index的方式(未測試)
CREATE FULLTEXT INDEX ft_email_name ON `student` (`name`)
也可以在建立索引的時候指定索引的長度:
CREATE FULLTEXT INDEX ft_email_name ON `student` (`name`(20))
刪除全文索引(未測試)
直接使用 drop index(注意:沒有 drop fulltext index 這種用法)
DROP INDEX full_idx_name ON tommy.girl ;
使用 alter table的方式
ALTER TABLE tommy.girl DROP INDEX ft_email_abcd;
使用全文索引
使用全文索引的格式: MATCH (columnName) AGAINST (‘string‘)
1. 自然語言模式下檢索:
得到合格個數
SELECT COUNT(*) FROM articles WHERE MATCH (title,body) AGAINST (‘資料庫‘ IN NATURALLANGUAGE MODE);
得到匹配的比率
SELECT id, MATCH (title,body) AGAINST (‘資料庫‘ IN NATURAL LANGUAGE MODE) AS score FROM articles;
2. 布爾模式下搜尋,這個就相對於自然模式搜尋來的複雜些:
匹配既有管理又有資料庫的記錄
SELECT * FROM articles WHERE MATCH (title,body) AGAINST (‘+資料庫 +管理‘ IN BOOLEAN MODE);
匹配有資料庫,但是沒有管理的記錄
SELECT * FROM articles WHERE MATCH (title,body) AGAINST (‘+資料庫 -管理‘ IN BOOLEAN MODE);
匹配MySQL,但是把資料庫的相關性降低
SELECT * FROM articles WHERE MATCH (title,body) AGAINST (‘>資料庫 +MySQL‘ INBOOLEAN MODE);
3. 查詢擴充模式,比如要搜尋資料庫,那麼MySQL,oracle,DB2也都將會被搜尋到
SELECT * FROM articles WHERE MATCH (title,body) AGAINST (‘資料庫‘ WITH QUERY EXPANSION);
4. ft_boolean_syntax (+ -><()~*:""&|)使用的例子:
+ : 用在詞的前面,表示一定要包含該詞,並且必須在開始位置。
eg: +Apple 匹配:"Apple123" , "tommy, Apple"
- : 不包含該詞,所以不能只用「-yoursql」這樣是查不到任何row的,必須搭配其他文法使用。
eg: MATCH (name) AGAINST (‘-lime +oracle‘)
匹配到: 所有不包含lime,但包含oracle的記錄
空(也就是預設情況),表示可選的,包含該詞的順序較高。
例子:
apple banana
找至少包含上面詞中的一個的記錄行。或的關係
+apple +juice
兩個詞均在被包含。與的關係
+apple macintosh
包含詞 “apple”,但是如果同時包含 “macintosh”,它的排列將更高一些
+apple -macintosh
包含 “apple” 但不包含 “macintosh”
> :提高該字的相關性,查詢的結果會排在比較靠前的位置。
< :降低相關性,查詢的結果會排在比較靠後的位置。
先不使用 >< 可以看到完全符合的排的比較靠前
select * from tommy.girl where match(girl_name) against(‘張欣婷‘ in boolean mode);
單獨使用 > 使用了>的李秀琴馬上就排到最前面了
select * from tommy.girl where match(girl_name) against(‘張欣婷 >李秀琴‘ in boolean mode);
單獨使用 < 看到沒,不是人也排到最前面了,這裡使用的可是 < 哦,說好的降低相關性呢,往下看吧。
select * from tommy.girl where match(girl_name) against(‘張欣婷 <不是人‘ in boolean mode);
同時使用>< 到這裡終於有答案了,只要使用了 ><的都會往前排,而且>的總是排在<的前面
1. 只要使用 ><的總比沒用的 靠前
2. 使用 >的一定比 <的排的靠前 (這就符合相關性提高和降低)
3. 使用同一類的,使用的越早,排的越前。
select * from tommy.girl where match(girl_name) against(‘張欣婷 >李秀琴 <練習冊 <不是人>是個鬼‘ in boolean mode);
( ):可以通過括弧來使用字條件。
eg: +aaa +(>bbb <ccc)
找到有aaa和bbb和ccc,aaa和bbb,或者aaa和ccc(因為bbb,ccc前面沒有+,所以表示可有可無),然後 aaa&bbb > aaa&bbb&ccc > aaa&ccc
~ :將其相關性由正轉負,表示擁有該字會降低相關性,但不像「-」將之排除,只是排在較後面。
eg: +apple ~macintosh 先匹配apple,但如果同時包含macintosh,就排名會靠後。
* :萬用字元,這個只能接在字串後面。
MATCH (girl_name) AGAINST (‘+*ABC*‘) #錯誤,不能放前面
MATCH (girl_name) AGAINST (‘+張筱雨*‘) #正確
" " :整體匹配,用雙引號將一段句子包起來表示要完全相符,不可拆字。
eg: "tommy huang" 可以匹配 tommy huang xxxxx 但是不能匹配 tommy is huang。
MyBatis 中 使用 全文索引注意:
前端傳入資料格式name:"",name:"lime oracle"
package com.das.mapper.service;import org.apache.commons.lang3.StringUtils;import org.apache.ibatis.jdbc.SQL;import java.util.HashMap;import java.util.Map;/** * @Author liangmy * @Date 2018/2/26 */public class ServiceBaseProvider { public String getServiceBaseList(Map<String, Object> map){ StringBuffer name = new StringBuffer(); for(String str : (null == map.get("name") ? " " : map.get("name").toString().trim() + " ").split(" ")){ name.append("+" + str + " "); } if(name.length() > 2) { name.deleteCharAt(name.length() - 1); } String level = null == map.get("level") ? "" : map.get("level").toString(); System.err.println(name); System.err.println(level); return new SQL(){ { SELECT("id"); FROM("service_base"); if(!StringUtils.isEmpty(name)) { WHERE("match(name) against(\"" + name.toString() + "\" in boolean mode)"); } if(!StringUtils.isEmpty(level)){ AND().WHERE("JSON_CONTAINS(level,‘" + level + "‘)"); } } }.toString(); }}
啦啦啦
MySQL使用全文索引(fulltext index)
InnoDB全文索引:N-gram Parser【轉】
MySQL 全文檢索索引 ngram Mybatis