Sphinx/屬性
屬性是附加在每個文檔上的額外的信息(值),可以在搜索的時候用于過濾和排序。
搜索結(jié)果通常不僅僅是進行文檔的匹配和相關(guān)度的排序,經(jīng)常還需要根據(jù)其他與文檔相關(guān)聯(lián)的值,對結(jié)果進行額外的處理。例如,用戶可能需要對新聞檢索結(jié)果依次按日期和相關(guān)度排序,檢索特定價格范圍內(nèi)的產(chǎn)品,檢索某些特定用戶的blog日志,或者將檢索結(jié)果按月分組。為了高效地完成上述工作,Sphinx允許給文檔附加一些額外的屬性,并把這些值存儲在全文索引中,以便在對全文匹配結(jié)果進行過濾、排序或分組時使用。
屬性與字段不同,不會被全文索引。他們僅僅是被存儲在索引中,屬性進行全文檢索式不可能的。如果要對屬性進行全文檢索,系統(tǒng)將會返回一個錯誤。
例如,如果column被設(shè)置為屬性,就不能使用擴展表達式@column 1去匹配column為1的文檔;如果數(shù)字字段按照普通的方式被索引,那么就可以這樣來匹配。
屬性可用于過濾,或者限制返回的數(shù)據(jù),以及排序或者 結(jié)果分組; 也有可能是完全基于屬性排序的結(jié)果, 而沒有任何搜索相關(guān)功能的參與. 此外, 屬性直接從搜索服務(wù)程序返回信息, 而被索引的文本內(nèi)容則沒有返回.
論壇帖子表是一個很好的例子。假設(shè)只有帖子的標題和內(nèi)容這兩個字段需要全文檢索,但是有時檢索結(jié)果需要被限制在某個特定的作者的帖子或者屬于某個子論壇的帖子中(也就是說,只檢索在SQL表的author_id和forum_id這兩個列上有特定值的那些行),或者需要按post_date列對匹配的結(jié)果排序,或者根據(jù)post_date列對帖子按月份分組,并對每組中的帖子計數(shù)。
可以通過名字來指示特定的屬性,并且這個名字是大小寫無關(guān)的(注意:直到目前為止,Sphinx還不支持中文作為屬性的名稱)。屬性并不會被全文索引,他們只是按原封不動的存儲在索引文件中。目前支持的屬性類型如下:
- 無符號整數(shù)(1-32位寬);
- UNIX時間戳(timestamps);
- 浮點值(32位,IEEE 754單精度);
- 字符串序列 (尤其是計算出的整數(shù)值);
- 多值屬性MVA( multi-value attributes ) (32位無符號整型值的變長序列).
由各個文檔的全部的屬性信息構(gòu)成了一個集合,它也被稱為文檔信息 docinfo. 文檔信息可以按如下兩種方式之一存儲:
- 與全文索引數(shù)據(jù)分開存儲(“外部存儲”,在.spa文件中存儲), 或者
- 在全文索引數(shù)據(jù)中,每出現(xiàn)一次文檔ID 就出現(xiàn)相應(yīng)的文檔信息(“內(nèi)聯(lián)存儲”,在.spd文件中存儲)
當采用外部存儲方式時,searchd總是在RAM中保持一份.spa文件的拷貝(該文件包含所有文檔的所有文檔信息)。這是主要是為了提高性能,因為磁盤的隨機訪問太慢了。相反,內(nèi)聯(lián)存儲并不需要任何額外的RAM,但代價是索引文件的體積大大地增加了;請注意,全部屬性值在文檔ID出現(xiàn)的每一處都被復制了一份,而文檔ID出現(xiàn)的次數(shù)恰是文檔中不同關(guān)鍵字的數(shù)目。僅當有一個很小的屬性集、龐大的文本數(shù)據(jù)集和受限的RAM時,內(nèi)聯(lián)存儲才是一個可考慮的選擇。在大多數(shù)情況下,外部存儲可令建立索引和檢索的效率都大幅提高。
檢索時,采用外部存儲方式產(chǎn)生的的內(nèi)存需求為 (1+number_of_attrs)*number_of_docs*4字節(jié),也就是說,帶有兩個屬性和一個時間戳的1千萬篇文檔會消耗(1+2+1)*10M*4 = 160 MB的RAM。這是每個檢索的守護進程(PER DAEMON)消耗的量,而不是每次查詢,searchd僅在啟動時分配160MB的內(nèi)存,讀入數(shù)據(jù)并在不同的查詢之間保持這些數(shù)據(jù)。子進程并不會對這些數(shù)據(jù)做額外的拷貝。