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