獲取搜索結果是進行搜索的最主要目的。通過 XSSearch::search 獲得搜索結果文檔, 如果沒有任何符合條件的匹配則會返回一個空數組。
在獲取搜索結果前您必須用上一章學到的知識先構造好相應的搜索語句$query
。
Note: 只有不帶參數的 XSSearch::search 搜索調用才會將關鍵詞記錄搜索日志中去。
默認情況下,每次返回搜索結果的前 10 條數據,您可以通過 XSSearch::setLimit 指定返回的條數及偏移量, 這樣就可以實現分頁搜索的效果。特別注意,每一次調用 XSSearch::search 后均會把這些設置恢復到默認值狀態(tài)。
$search->setLimit(5); // 設置返回結果為前 5 條
$search->setLimit(5, 15); // 設置返回結果為 5 條,但要先跳過 15 條,即第 16~20 條。
默認情況,搜索結果根據內部算法計算相關度進行排序,采用著名的 BM25
算法,這在信息檢索概率模型中表現 非常優(yōu)秀,通常只要使用默認的算法即可。
通過 XSSearch::setSort 我們可以指定讓搜索結果按照某一個字段的值進行正序或倒序排列,參考代碼:
$search->setSort('chrono'); // 按 chrono 字段的值倒序
$search->setSort('chrono', true); // 按 chrono 字段的值正序排列
自從 1.1.0 版本起,通過 XSSearch::setMultiSort 可以實現按照多字段的值排序, 它接受一個數組參數用于表述排序的方式。以字段名稱為鍵,用 true/false 值來表示是否需要正序排列, 默認為 false 表示逆序排列。參見以下代碼:
// 表示先以 chrono 正序、再以 pid 逆序(pid 是字符串并不是數值所以 12 會排在 3 之后)
$sorts = array('chrono' => true, 'pid' => false);
// 如果直接把字段名作為數組的值,默認對該字段采用逆序,因此以上用法和下面用法是完全一樣的
$sorts = array('chrono', 'pid' => false);
// 設置搜索排序
$search->setMultiSort($sorts);
Note: 按字段值排序是一個低效能的行為,如非必要,強烈建議使用默認排序方式。 排序默認也是按照字節(jié)序比較,對于數字型的字段請將字段類型設為
numeric
。為了兼容,您也可以把多字段排序的參數直接傳遞給 XSSearch::setSort 即可。
調用 XSSearch::search 后返回的是搜索結果文檔對象組成的數組, 您直接使用這些文檔對象的屬性即可。
// 以 demo 項目的配置為例
$docs = $search->setQuery('測試')->setLimit(5)->search();
foreach ($docs as $doc){
// 其中常用魔術方法:percent() 表示匹配度百分比, rank() 表示匹配結果序號
echo $doc->rank() . '. ' . $doc->subject . " [" . $doc->percent() . "%] - ";
echo date("Y-m-d", $doc->chrono) . "\n" .
$doc->message . "\n";
}
根據搜索的習慣,通會希望讓搜索結果中匹配關鍵詞的部分進行飄紅或加粗等高亮處理, 由于其中涉及到了分詞等細節(jié)處理比較麻煩。因此,我們統(tǒng)一提供了 XSSearch::highlight 方法,可以對搜索結果文檔中的字段值直接進行處理,匹配關鍵詞部分會自動套上 em
標簽。
您只要在 CSS
中定義它即可實現自己的高亮代碼。
$docs = $search->setQuery('測試')->setLimit(5)->search();
foreach ($docs as $doc) {
$subject = $search->highlight($doc->subject);
// 高亮處理 subject 字段
$message = $search->highlight($doc->message);
// 高亮處理 message 字段
echo $doc->rank() . '. ' . $subject . " [" . $doc->percent() . "%] - ";
echo date("Y-m-d", $doc->chrono) . "\n" . $message . "\n";
}
Note: 這個方法不適合于快捷搜索,也就是說必須使用
setQuery
以及不帶參數的search
才有效。
有時我們也反折疊搜索稱為歸并搜索,就像 Google
上通常搜索結果中對于某一個網站只會顯示 2 條最匹配的結果, 其余的歸并折疊起來。
在 Xunsearch
中,通過 XSSearch::setCollapse 可以設置按照指定字段的值歸并搜索結果,其中第二參數可以 指定歸并后返回數量,默認為 1。對于這種情況,請在搜索結果文檔中調用 $doc->ccount()
獲取展開的全部匹配數。
// 表示搜索結果按 tid 字段的值歸并,至多返回 1 條最匹配的數據
$search->setCollapse('tid');
// 然后正常進行搜索后得到的搜索結果文檔
$docs = $search->search();
foreach ($docs as $doc) {
// 輸出 $doc 的有關信息
// 得出相同 tid 下還有多少條匹配信息
echo '該主是下還有 ' . ($doc->ccount() - 1) . ' 條匹配結果。';
}
更多建議: