文檔說明

構建搜索語句

搜索查詢力爭做到簡單明了,和目前最流行的搜索引擎做法極為相似,并不需要過多額外的修飾或語法。

您只要把您打算搜索的短語或關鍵詞列出來即可,建議用空格連接多個詞;在此基礎上還支持字段搜索、 布爾搜索、精確搜索、相鄰位置搜索等。

1. 典型搜索語句

正如上面所講,僅僅用空格把搜索詞、名子連接起來的方式最為常用。內部默認采用 AND 規則, 也就是說要求列出來的關鍵詞(分詞之后)全部匹配,如果您通過 XSSearch::setFuzzy 開啟了模糊匹配,那么相當于采用 OR 規則,只要其中一個關鍵詞匹配即可。

剛剛說的這種搜索的是索引數據庫的“混合區”,即類型為 body 的字段以及索引方式為 mixedboth 的字段。如果某個字段的索引方式為 selfboth,那么還可以指定為字段檢索, 也就是要求這個字段匹配指定的關鍵詞,用法為格式為 “字段名:關鍵詞”。

Note: 搜索語句最大支持長度為 80 字節(每一個漢字占 3 字節),此規則同時適用于 XSSearch::searchXSSearch::count$query 參數。

搜索語句舉例如下:

$search->search('上海人民公園'); // 檢索 body 型字段及混合區
$search->search('上海 人民公園'); // 用空格連接 2 個關鍵詞, 這種情況比上面的用法更明確
$search->search('subject:上海 人民公園'); // 特別要求 subject 字段包含 "上海"
$search->setFuzzy()->search('上海公園'); // 開啟模糊搜索,搜索 "上海" 或 "公園"

Tip: 從 1.3.0 版本起,允許使用空搜索條件進行搜索了,其含義相當于全部匹配

2. 布爾搜索

出于高級搜索的需求,我們的搜索語句還全面支持布爾操作,并且像數學運算一樣支持括號操作以明確關系。

多個詞語之間的“并且”、“或者”、“異或”關系

默認情況,系統采用“并且”關系,即您輸入的多個詞語(空格分開或系統自動切分以后)必須全部包含。 您也可以通過 AND 將這些關鍵詞顯式的強制要求全部出現。相應的,如果您需要只包括其中一個詞即可, 那么用 OR 將它們連接起來。更有趣的是,如果有些情況您只想要其中的一個詞,并且不要兩者同時出現, 那么就用 XOR 連接。參看下面的例子:

Note: 表達布爾關系的關鍵字必須全部大寫,即:XOR, OR, AND

$search->search('杭州 西湖');
$search->search('杭州 AND 西湖'); // 這兩者效果是相同的
 
$search->setFuzzy()->search('杭州 西湖');
$search->search('杭州 OR 西湖');  // 這兩者效果相同,都是只要求匹配其中一個
 
$search->search('杭州 XOR 西湖'); // 表示必須包含其中一個詞,并且不允許同時包含這兩個詞。

要求搜索結果中不含特定關鍵詞

如果您發現搜索結果中,有某一類信息是您不希望看見的,而且這些信息都包含特定的關鍵詞,那么請用減號或 NOT 語法,就可以去除所有這些含有特定關鍵詞的網頁。例如,搜索 “神雕俠侶”,希望是關于武俠小說方面 的內容,卻發現很多關于電視劇方面的網頁。這時希望排除所有包含“電視劇”的搜索結果。

Note: 前一個關鍵詞和減號之間必須有空格分開,否則會被當連字符處理,減號和后一個關鍵詞之間不能有空格。

$search->search('神雕俠侶 -電視劇'); // 正確用法1
$search->search('神雕俠侶 NOT 電視劇'); // 正確用法2
 
$search->search('神雕俠侶-電視劇'); // 不符合預期目的
$search->search('神雕俠侶 - 電視劇'); // 不符合預期目的

組合關系的括號表達式

就像數學表達式中,括號具有顯式的優先級,如果您需要非常復雜的搜索條件,就采用括號表達式來組合上述的條件。

// 要求結果包含 “杭州+西湖” 或 “杭州 + 西溪濕地”,并且不能包含 “汽車 火車”
$search->search('((杭州 AND 西湖) OR (杭州 AND 西溪濕地)) NOT (汽車 火車)');

Tip: 在組合關鍵中允許嵌入字段搜索的語法。如:subject:上海 OR subject:公園

3. 精確搜索

在項目字段設計中有一個選項 phrase 如果設為 yes 將在索引數據庫中保存關鍵詞的位置信息, 因而我們可以在搜索時利用這些位置信息實現精確搜索。

Info: 項目中類型為 title、body 的字段默認已開啟此項,此外這個選項也僅針對使用內置分詞器的字段有效。 對于 phrase 設為 no 或用其它分詞器的字段來說這項功能無效。

使用雙引號進行精確匹配

如果輸入的查詢詞較長,在經過系統詞法分析后,給出的搜索結果中的查詢詞,可能是拆分的。 如果您對這種情況不滿意,可以嘗試給查詢短句加上雙引號,搜索結果就會要求詞按順序匹配。

$search->search('上??萍即髮W');
// 這時內部把搜索語句切割為:上海+科技+大學,要求搜索結果同時包含這三個詞即可,
// 但不要求它們的出現順序,有可能先出現”科技“再出現”上?!?,也有可能這三個詞離得很遠。
 
$search->search('"上??萍即髮W"');
// 加上引號后,要求搜索結果必須依次出現”上海+科技+大學“,要顯得精準很多。

索引詞之間的距離查詢

如果您希望輸入的多個關鍵詞之間的在匹配結果中的位置距離不要太遠,那么可以使用 NEAR 語法來進行搜索,默認要求它們的距離不超過 10。您還可以在 NEAR 后加上 /n 表示 具體的距離要求,n 是整數,這兒的距離指的是分詞后的序號距離。

$search->search('杭州 NEAR 西湖'); // 要求結果中出現 "杭州" 和 "西湖",并且距離不超過 10 個詞
$search->search('杭州 NEAR/5 西湖'); // 要求它們距離不超過 5個詞

如果您還希望檢索結果中詞匯出現的順序與您的輸入順序一致,只要將 NEAR 換成 ADJ 即可, 注意這些語法詞和布爾搜索一樣,均必須全部大寫。

$search->search('杭州 ADJ 西湖'); // 要求結果中先出現 "杭州" 再出現 "西湖",并且距離不超過 10 個詞
$search->search('杭州 ADJ/3 西湖'); // 要求它們距離不超過 3個詞
4. 其它搜索語句修飾

前面還有提到一些附加的搜索語句修飾,這些操作不能直接寫進 Query 語句,只能過過相應的 API 來完成。

字段值區間搜索

通過 XSSearch::addRange 我們可以在搜索中,針對某個字段的值增加區間條件過濾。該方法接受三個參數, 第一參數 $field 為字段名稱,后面兩個參數依次是 $from 起始值,$to 結束值。假設該字段的值為 $value,那么要求 $value > $from && $value <= $to 才符合條件,其中如果有一個設為 null, 則會自動將區間轉換為單向比較。

以前面提到的 demo 項目中的 chrono 字段為例,參看下面代碼及注釋:

$from = strtotime("2011-1-1"); // 起始時間 2011年1月1日
$to = strtotime("2011-9-1"); // 結束時間 2011年9月1日
 
// 1. <= $to: 要求結果的時間必須在 2011-9-1 之前,并且包含 2011-9-1
$docs = $search->setQuery('杭州')->addRange('chrono', null, $to)->search();
 
// 2. >= $from: 要求結果的時間必須在 2011-1-1 之后,并且包含 2011-1-1
$docs = $search->setQuery('杭州')->addRange('chrono', $from, null)->search();
 
// 3. > $from && <= $to: 要求結果的時間必須在 2011-1-1 之后 并且 2011-9-1 之前
$docs = $search->setQuery('杭州')->addRange('chrono', $from, $to)->search();

按字段索引詞加權

通過 XSSearch::addWeight 我們可以針對某個字段添加權重索引詞。該字段是否包含這個詞 都不影響搜索匹配結果,但如果包含會參與計算結果權重,使結果的相關度更高。常用于針對某一類 數據提升搜索結果排序位置。

// 搜索包含 "杭州" 的結果,并且提升 subject 字段包含 "西湖" 的數據的排序
$docs = $search->setQuery('杭州')->addWeight('subject', '西湖')->search();

Note: 這些修飾不能應用到快捷搜索中,也就是說不能直接把 Query 語句傳遞給 XSSearch::search。 您必須用 XSSearch::setQuery 設置搜索語句,再用不帶參數的調用 searchcount 方法。

區間搜索默認用的是字節序比較,如果您希望將字段值以數字方式比較大小,請將字段的類型設置為 numeric。

5. 查看搜索語句的分析結果

通過 XSSearch::setQuery 設置了搜索語句后,您可以調用 XSSearch::getQuery 查看您的搜索語句 在內部的分析結果,常用于 DEBUG。此外這兩個方法也可以通過魔術屬性 XSSearch::query 來訪問。

// 設置搜索語句方法1:
$search->setQuery('神雕俠侶 -電視劇');
 
// 設置搜索語句方法2:
$search->query = '神雕俠侶 -電視劇';
 
// 查看搜索語句解析結果方法1:
// 不帶參數,輸出:Xapian::Query((神雕俠侶:(pos=1) AND_NOT 電視劇:(pos=2)))
echo $search->getQuery();
 
// 帶參數,則解析新語句,輸出:Xapian::Query((杭州:(pos=1) AND 西湖:(pos=2)))
echo $search->getQuery('杭州 西湖'); 
 
// 查看搜索語句解析結果方法2:
// 相當于不帶參數的調用 getQuery()
echo $search->query;
$Id$

8條評論!

#123 報告
lifetin at 2018-02-20 16:11:22
addRange 就沒有=的條件嗎?

addRange 就沒有=的條件嗎?

#122 報告
AAAAA at 2018-02-11 14:00:26
怎么可以在構建查詢語句的時候只匹配一個字段

緩存db文件里,有三個字段,怎么可以在構建查詢語句的時候只匹配一個字段 比如:有id,name,content,三個字段,緩存db已經跑完,在不改緩存的文件的情況下,怎么可以只匹配一個name字段? 還是說緩存db跑完后,配置文件不可更改? 感覺這個文檔真的很迷

#121 報告
雨林峰 at 2018-02-08 10:44:27
疑問

也沒有開發人員定時解決bug

#110 報告
大腿無敵 at 2017-08-30 17:21:50
文檔不全

太爛了

#86 報告
makediff at 2016-08-31 18:57:46
文檔真爛

文檔真爛

#74 報告
jinshan at 2016-03-16 15:55:15
多個條件范圍查詢問題

多個條件范圍查詢addRange(),條件之間 OR 的關系該怎樣查詢?

#65 報告
guojia at 2015-11-27 15:25:38
setFuzzy()必須在setQuery之前,請文檔里面說明下

今天這個折騰了倆小時~~~~

#42 報告
李小向 at 2014-06-20 15:40:19
貌似沒有辦法直接使用不含特定關鍵子查詢

貌似沒有辦法直接使用不含特定關鍵子查詢,只能在使用其他查詢的條件下再聯合使用NOT?

請到論壇 登錄 后刷新本頁面!

青海快三开奖走势图_ 舟山体彩飞鱼中奖技巧 北京pk10计划软件 精准 幸运农场复式中奖表 甘肃快3基本走势 一定牛 大发快三 股票投资必看十大书籍 3d试机号203历史开奖号 开股票配资公司 河北快三预测 幸运赛车人工计划