[coreseek/sphinx學習筆記4]--搜索

[參考Coreseek 全文檢索服務器 2.0 (Sphinx 0.9.8)參考手冊,詳情見 http://www.coreseek.cn/docs/sphinx_doc_zhcn_0.9.pdf  

4.1 匹配模式
有以下可選的匹配模式:
    SPH_MATCH_ALL, 匹配全部查詢詞(默認模式)
    SPH_MATCH_ANY, 匹配查詢詞中的任意一個
    SPH_MATCH_PHRASE, 將整個查詢看做一個詞組,要求按順序完整匹配
    SPH_MATCH_BOOLEAN, 將查詢看做一個布爾表達式
    SPH_MATCH_EXTENDED, 將查詢看做一個 Sphinx 內部查詢語言的表達式
還有一個特殊的「完整掃描」模式,當以下條件知足時,該模式被自動激活:
    查詢串是空的(即長度爲零)
    docinfo存儲方式爲 extern
算法

4.2 權重計算
採用何種權值計算函數(目前)取決於查詢的模式。
There are these major parts which are used in the weighting functions:
權值計算函數進行以下兩部分主要部分: 1. 詞組評分  2. 統計學評分
    詞組評分根據文檔和查詢的長公共子串(LCS,longest common subsequence)的長度進行。
所以若是文檔對查詢詞組有一個精確匹配(即文檔直接包含該詞組),那麼它的詞組評分就取得了可能的最大值,也就是查詢中詞的個數。
    統計學評分基於經典的 BM25 函數,該函數僅考慮詞頻。若是某詞在整個數據庫中不多見(即文檔集上的低頻詞)或者在某個特定文檔中被常常說起(即特定文檔上的高頻詞),那麼它就獲得一個較高的權重。最終的 BM25 權值是一個 0 到 1 之間的浮點數。 數據庫

在全部模式中,數據字段的詞組評分是 LCS 乘以用戶指定的數據字段權值。數據字段權值是整數,默認爲 1,且字段的權值必須不小於 1。
    在 SPH_MATCH_BOOLEAN 模式中,不作任何權重估計,每個匹配項的權重都是 1。
    在 SPH_MATCH_ALL 和 SPH_MATCH_PHRASE 模式中,最終的權值是詞組評分的加權和。
    在 SPH_MATCH_ANY 模式中,於前面述兩模式的基本思想相似,只是每一個數據字段的權重都再加上一個匹配詞數目。在那以前,帶權的詞組相關度被額外乘以一個足夠大的數,以便確保任何一個有較大詞組評分的數據字段都會使整個匹配的相關度較高,即便該數據字段的權重比較低。
    在 SPH_MATCH_EXTENDED 模式中,最終的權值是帶權的詞組評分和 BM25 權重的和,再乘以 1000 並四捨五入到整數。
    這個行爲將會被修改,以便使 MATCH_ALL 和 MATCH_ANY 這兩個模式也能使用 BM25 算法。這將使詞組評分相同的搜索結果片段獲得改進,這在只有一個詞的查詢中尤爲有用。
    關鍵的思想(對於除布爾模式之外的所有模式中)是子詞組的匹配越好則評分越高,精確匹配(匹配整個詞組)評分最高。這種基於詞組類似性的評分方法能夠提供比任何單純的統計模型(好比其餘搜索引擎中普遍使用的 BM25)明顯更高的搜索質量。

4.3 排序模式
可以使用以下模式對搜索結果排序:
    SPH_SORT_RELEVANCE 模式, 按相關度降序排列(好的匹配排在最前面)
    SPH_SORT_ATTR_DESC 模式, 按屬性降序排列(屬性值越大的越是排在前面)
    SPH_SORT_ATTR_ASC 模式, 按屬性升序排列(屬性值越小的越是排在前面)
    SPH_SORT_TIME_SEGMENTS 模式, 先按時間段(最近一小時/天/周/月)降序,再按相關度降序
    SPH_SORT_EXTENDED 模式, 按一種相似 SQL 的方式將列組合起來,升序或降序排列。
    SPH_SORT_EXPR 模式,按某個算術表達式排序。
    SPH_SORT_RELEVANCE 忽略任何附加的參數,永遠按相關度評分排序。全部其他的模式都要求額外的排序子句,子句的語法跟具體的模式有關。
    SPH_SORT_ATTR_ASC,SPH_SORT_ATTR_DESC 以及 SPH_SORT_TIME_SEGMENTS 這三個模式僅要求一個屬性名。
    SPH_SORT_RELEVANCE 模式等價於在擴展模式中按"@weight DESC, @id ASC"排序,SPH_SORT_ATTR_ASC 模式等價於"attribute ASC, @weight DESC, @id ASC",而SPH_SORT_ATTR_DESC 等價於"attribute DESC, @weight DESC, @id ASC"。
    SPH_SORT_TIME_SEGMENTS 模式在 SPH_SORT_TIME_SEGMENTS 模式中,屬性值被分割成「時間段」,而後先按時間段排序,再按相關度排序。
    時間段是根據搜索發生時的當前時間戳計算的,所以結果隨時間而變化。所說的時間段有以下這些值:
    最近一小時
    最近一天
    最近一星期
    最近一個月
    最近三個月
    其餘值
    時間段的分法固化在搜索程序中了,但若是須要,也能夠比較容易地改變(須要修改源碼)。
    這種模式是爲了方便對 Blog 日誌和新聞提要等的搜索而增長的。使用這個模式時,處於更近時間段的記錄會排在前面,可是在同一時間段中的記錄又根據相關度排序-這不一樣於單純按時間戳排序而不考慮相關度。
    SPH_SORT_EXTENDED 模式在 SPH_SORT_EXTENDED 模式中,您能夠指定一個相似 SQL 的排序表達式,但涉及的屬性(包括內部屬性)不能超過 5 個,例如:
    @relevance DESC, price ASC, @id DESC
    只要作了相關設置,不論是內部屬性(引擎動態計算出來的那些屬性)仍是用戶定義的屬性就均可以使用。內部屬性的名字必須用特殊符號@開頭,用戶屬性按原樣使用就好了。在上面的例子裏,@relevance 和@id 是內部屬性,而 price 是用戶定義屬性。
已知的內部屬性:
    @id (match ID)
    @weight (match weight)
    @rank (match weight)
    @relevance (match weight)
    @id(匹配的 ID)
    @weight(匹配權值)
    @rank(匹配權值)
    @relevance(匹配權值)
    @rank 和@relevance 只是@weight 的額外別名。

SPH_SORT_EXPR 模式
    表達式排序模式使您能夠對匹配項按任何算術表達式排序,表達式中的項能夠是屬性值,內部屬性(@id 和@weight),算術運算符和一些內建的函數。例如:
    $cl->SetSortMode ( SPH_SORT_EXPR,"@weight + ( user_karma + ln(pageviews) )*0.1" );
    支持的運算符和函數以下。它們是模仿 MySQL 設計的。函數接受參數,參數的數目根據具體函數的不一樣而不一樣。
    Operators: +, -, *, /, <, > <=, >=, =, <>.
    Unary (1-argument) functions: abs(), ceil(), floor(), sin(), cos(), ln(), log2(), log10(), exp(),sqrt().
    Binary (2-argument) functions: min(), max(), pow().
    Ternary (3-argument) functions: if().
運算符: +, -, *, /, <, > <=, >=, =, <>.
一元函數(一個參數):abs(), ceil(), floor(), sin(), cos(), ln(), log2(), log10(), exp(),sqrt().
二元函數(兩個參數):min(), max(), pow().
三元函數(三個參數):if().
    所有的計算都以單精度 32 位 IEEE754 浮點數進行。比較操做符(好比=和<=)在條件爲真時返回 1.0,不然返回 0.0。例如(a=b)+3 在屬性「a」與屬性「b」相等時返回 4,不然返回3。與 MySQL 不一樣,相等性比較符(即=和<>)中引入了一個小的閾值(默認是 1e-6)。
    若是被比較的兩個值的差別在閾值以內,則兩者被認爲相等。
    所有的一元和二元函數的意義都很明確,他們的行爲跟在數學中的定義同樣。但 IF()的行爲須要點詳細的解釋。它接受 3 個參數,檢查第一個參數是否爲 0.0,若非零則返回第二個參數,爲零時則返回第三個參數。注意,與比較操做符不一樣,IF()並不使用閾值!所以在第一個參數中使用比較結果是安全的,但使用算術運算符則可能產生意料以外的結果。好比,下面兩個調用會產生不一樣的結果,雖然在邏輯上他們是等價的:
    IF ( sqrt(3)*sqrt(3)-3<>0, a, b )
    IF ( sqrt(3)*sqrt(3)-3, a, b )
    在第一種狀況下,因爲有閾值,比較操做符<>返回 0.0(邏輯假),因而 IF()老是返回‘b’。在第二種狀況下,IF()函數親自在沒有閾值的狀況下將一樣的sqrt(3)*sqrt(3)-3 與零值作比較。但因爲浮點數運算的精度問題,該表達式的結果與0 值會有微小的差別,所以該值與零值的相等比較不會經過,上述第二種狀況中 IF()會返回‘a’作爲結果。

4.4 結果分組(聚類)
    有時將搜索結果分組(或者說「聚類」)並對每組中的結果計數是頗有用的-例如把找到的論壇帖子按其做者分組。
    理論上,這能夠分兩步實現:首先在 Sphinx 中作全文檢索,再在 SQL 服務器端對獲得的 ID分組。可是現實中在大結果集(10K 到 10M 個匹配)上這樣作一般會嚴重影響性能。
    爲避免上述問題,Sphinx 提供了一種「分組模式」,能夠用 API 調用 SetGroupBy()來開啓。
    在分組時,根據 group-by 值給匹配項賦以一個分組。這個值用下列內建函數之一根據特定的屬性值計算:
    SPH_GROUPBY_DAY,從時間戳中按 YYYYMMDD 格式抽取年、月、日
    SPH_GROUPBY_WEEK,從時間戳中按 YYYYNNN 格式抽取年份和指定週數(自年初計起)的第一天
    SPH_GROUPBY_MONTH,從時間戳中按 YYYYMM 格式抽取月份
    SPH_GROUPBY_YEAR,從時間戳中按 YYYY 格式抽取年份
    SPH_GROUPBY_ATTR,使用屬性值自身進行分組
    最終的搜索結果中每組包含一個最佳匹配。分組函數值和每組的匹配數目分別以「虛擬」屬性@group 和@count 的形式返回。
    結果集按 group-by 排序子句排序,語法與 SPH_SORT_EXTENDED 排序子句的語法類似。除了@id 和@weight,分組排序子句還包括:
    @group(groupby 函數值)
    @count(組中的匹配數目)
    默認模式是根據 groupby 函數值降序排列,即按照「@group desc」排序完成時,結果參數 total_found 會包含在整個索引上匹配的組的總數目。
    注意:分組操做在固定的內存中執行,所以它給出的是近似結果;因此 total_found 報告的數目可能比實際給出的個分組數目的和多。@count 也可能被低估。要下降不許確性,應提升max_matches。若是 max_matches 容許存儲找到的所有分組,那結果就是百分之百準確的。
    例如,若是按相關度排序,同時用 SPH_GROUPBY_DAY 函數按屬性「published」分組,那麼:
    結果中包含天天的匹配結果中最相關的那一個,若是那天有記錄匹配的話。
    結果中還附加給出天的編號和天天的匹配數目
    結果以天的編號降序排列(即最近的日子在前面)

4.5 分佈式搜索
爲提升可伸縮性,Sphnix 提供了分佈式檢索能力。分佈式檢索能夠改善查詢延遲問題(即縮短查詢時間)和提升多服務器、多 CPU 或多核環境下的吞吐率(即每秒能夠完成的查詢數)。這對於大量數據(即十億級的記錄數和 TB 級的文本量)上的搜索應用來講是很關鍵的。

    其關鍵思想是將待搜索數據作水平分區(HP,Horizontally partition),而後並行處理。
分區不能自動完成,您須要:
    在不一樣服務器上設置 Sphinx 程序集(indexer 和 searchd)的多個實例
    讓這些實例對數據的不一樣部分作索引(並檢索)
    在 searchd 的一些實例上配置一個特殊的分佈式索引
    而後對這個索引進行查詢
    這個特殊索引只包括對其餘本地或遠程索引的引用,所以不能對它執行從新創建索引的操做,相反,若是要對這個特殊索引進行重建,要重建的是那些被這個索引被引用到的索引。
    當 searchd 收到一個對分佈式索引的查詢時,它作以下操做:
    1. 鏈接到遠程代理
    2. 執行查詢
    3. (在遠程代理執行搜索的同時)對本地索引進行查詢
    4. 接收來自遠程代理的搜索結果
    5. 將全部結果合併,刪除重複項
    6. 將合併後的結果返回給客戶端
    在應用程序看來,普通索引和分佈式索引徹底沒有區別。
    任一個 searchd 實例能夠同時作爲主控端(master,對搜索結果作聚合)和從屬端(只作本地搜索)。這有以下幾點好處:
    1. 集羣中的每臺機器均可以作爲主控端來搜索整個集羣,搜索請求能夠在主控端之間得到負載平衡,至關於實現了一種 HA(high availability,高可用性),能夠應對某個節點失效的狀況。
    2. 若是在單臺多 CPU 或多核機器上使用,一個作爲代理對本機進行搜索的 searchd 實例就能夠利用到所有的 CPU 或者核。
    更好的 HA 支持已在計劃之中,到時將容許指定哪些代理之間互相備份、有效性檢查、跟蹤運行中的代理、對檢索請求進行負載均衡,等等。

4.6 searchd 日誌格式
searchd 將所有成功執行的搜索查詢都記錄在查詢日誌文件中。如下是一個相似記錄文件的例子:
    [Fri Jun 29 21:17:58 2007] 0.004 sec [all/0/rel 35254 (0,20)] [lj] test
    [Fri Jun 29 21:20:34 2007] 0.024 sec [all/0/rel 19886 (0,20) @channel_id] [lj] test
日誌格式以下
    [query-date] query-time [match-mode/filters-count/sort-mode
    total-matches (offset,limit) @groupby-attr] [index-name] query
匹配模式(match-mode)能夠是以下值之一:
    "all" 表明 SPH_MATCH_ALL 模式;
    "any" 表明 SPH_MATCH_ANY 模式;
    "phr" 表明 SPH_MATCH_PHRASE 模式;
    "bool" 表明 SPH_MATCH_BOOLEAN 模式;
    "ext" 表明 SPH_MATCH_EXTENDED 模式.

排序模式(sort-mode)能夠取以下值之一:
    "rel" 表明 SPH_SORT_RELEVANCE 模式;
    "attr-" 表明 SPH_SORT_ATTR_DESC 模式;
    "attr+" 表明 SPH_SORT_ATTR_ASC 模式;
    "tsegs" 表明 SPH_SORT_TIME_SEGMENTS 模式;
    "ext" 表明 SPH_SORT_EXTENDED 模式. 安全

相關文章
相關標籤/搜索