sphinx簡析

CSphSource 數據源
CSphSource_XMLPipe2-XML文件獲取數據
CSphSource_SQL-SQL(MySQL)獲取數據


CSphIndex 索引器
派生類CSphIndex_VLN
// 索引過程
virtual int Build ( CSphDict * pDict,
const CSphVector & dSources, // 所有數據源
int iMemoryLimit, // 內存設置
ESphDocinfo eDocinfo );

/// available docinfo storage strategies
enum ESphDocinfo
{
       SPH_DOCINFO_NONE        = 0, ///< no docinfo available
       SPH_DOCINFO_INLINE            = 1, ///< inline docinfo into index (specifically, into doclists)
       SPH_DOCINFO_EXTERN          = 2         ///< store docinfo separately
};


  
BYTE ** CSphSource_SQL::NextDocument ( CSphString & sError )
{
m_tDocInfo.m_iDocID = sphToDocid ( SqlColumn(0) ); // 取得文檔ID值
}

bool CSphSource_Document::IterateHitsNext ( CSphString & sError )
{
while ( ( sWord = m_pTokenizer->GetToken() )!=NULL ) //分詞
}


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


CSphAutofile fdTmpDocinfos (“tmp2″) // 存儲文檔信息

DOCINFO2ID(pDocinfo) = pSource->m_tDocInfo.m_iDocID; // 自定義ID
memcpy ( DOCINFO2ATTRS(pDocinfo), pSource->m_tDocInfo.m_pRowitems, sizeof(CSphRowitem)*m_tSchema.GetRowSize() );
pDocinfo += iDocinfoStride;

Sphinx使用的文件包括 “sph”, “spa”, “spi”, “spd”, “spp”, “spm” ,還有鎖文件。其中sph是系統的配置文件。其它則爲索引文件。

.Spi 文件:保存WordId及指向此WordId對應的文檔信息在spd文件的指針。Spi文件在檢索程序啓動時完全加載入內存。Spi文件是分塊的,塊內排序,塊之間也排序。分塊的目的應該是爲了快速檢索到WordId,因爲Spi中的WordId是變長壓縮的,索引需要先在塊級別做二分定位,再在快內解壓縮查找。
文件結構,每塊中結構,wordId實際存儲的是差值
WordId | SpdFilePointer | DocNum | HitNum

.Spd文件:文件結構

DocID | [DocInfo] | HitFilePointer | FieldNum | HitNum

.Spp文件: 文件結構
HitPos

.Spa文件:存儲DocInfo的文件,檢索程序啓動時會把此文件加載如內存,sphinx可以指定DocInfo的存儲方式,
① 存儲到spd文件中(InLine)
②. 另外單獨存儲。指定此,就會生成spa文件
文件結構:
DocId | DocInfo

.Spm文件:在DocInfo中,有一種特殊的屬性,叫MVA,多值屬性。Sphinx對此屬性特殊處理,需要存儲在spm文件中。檢索程序啓動時會把此文件加載如內存。此(MVA)屬性在DocInfo對應位置存儲其在此文件中的字節偏移量。
文件結構:
DocId | Anum,A1,A2,…,An | Bnum,B1,B2,…,Bn | …

由於在第一趟掃描過程中會出現WordID相同的不同Hits(不同文檔或者不同位置不同字段),二趟前會根據WordID排序,WordID相同的Hits會連續出現併合並(合併到第一次出現的相同WordID中)

/////////////////////////////////////////////

Spi文件

// 遍歷所有的數據源
// 遍歷所有的文檔
struct CSphWordHit
{
    SphDocID_t    m_iDocID;     ///< document ID
    SphWordID_t       m_iWordID;    ///< word ID in current dictionary
    DWORD         m_iWordPos;       ///< word position in current document
};
CSphWordHit.. CSphWordHit…CSphWordHit…CSphWordHit串接
dHitBlocks.Add( cidxWriteRawVLB ( fdTmpHits.GetFD(), dHits, iHits, NULL, 0, 0 ) );//
GetIndexFileName(“tmp1″) 將Hits流寫入tmp1文件。臨時文件
不論重複,不論字段

dBins->ReadHit(&tHit,iRowitems,dInlineAttrs+i*iRowitems )// 重新讀入內存

cidxHit(tQueue.m_pData,iRowitems?dInlineAttrs+iBin*iRowitems : NULL );
// 統計後刷入m_wrWordlist,形如以下字節流(有緩衝,緩衝滿則寫入磁盤)
WordId | SpdFilePointer | DocNum | HitNum

此時寫入的是最終的索引文件,格式如上


Spd文件

文件結構
DocID | [DocInfo] | HitFilePointer | FieldNum | HitNum

//tQuery.m_eMode = SPH_MATCH_ANY;
   tQuery.m_eMode = SPH_MATCH_BOOLEAN;
   //tQuery.m_eMode = SPH_MATCH_PHRASE;
   //tQuery.m_eMode = SPH_MATCH_EXTENDED;
   //tQuery.m_eMode = SPH_MATCH_EXTENDED2;

   //SPH_SORT_RELEVANCE 模式, 按相關度降序排列(最好的匹配排在最前面)
   //SPH_SORT_ATTR_DESC 模式, 按屬性降序排列(屬性值越大的越是排在前面)
   //SPH_SORT_ATTR_ASC模式, 按屬性升序排列(屬性值越小的越是排在前面)
   //SPH_SORT_TIME_SEGMENTS 模式, 先按時間段(最近一小時/天/周/月)降序,再按
   // 相關度降序
   //SPH_SORT_EXTENDED 模式, 按一種類似SQL的方式將列組合起來,升序或降序排
   // 列。
   //SPH_SORT_EXPR 模式,按某個算術表達式排序。



       switch ( pQuery->m_eMode )
       {
case SPH_MATCH_ALL:                    bMatch = MatchAll ( pQuery, pResult, iSorters, ppSorters ); break;// 與查詢
case SPH_MATCH_PHRASE:             bMatch = MatchAll ( pQuery, pResult, iSorters, ppSorters ); break;//短語查詢
case SPH_MATCH_ANY:                   bMatch = MatchAny ( pQuery, pResult, iSorters, ppSorters ); break; //或查詢
case SPH_MATCH_BOOLEAN:        bMatch = MatchBoolean ( pQuery, pResult, iSorters, ppSorters, tTermSetup ); break;//布爾查詢
case SPH_MATCH_EXTENDED:       bMatch = MatchExtendedV1 ( pQuery, pResult, iSorters, ppSorters, tTermSetup ); break;//擴展查詢
case SPH_MATCH_EXTENDED2:     bMatch = MatchExtended ( pQuery, pResult, iSorters, ppSorters, tTermSetup ); break;
case SPH_MATCH_FULLSCAN:       bMatch = MatchFullScan ( pQuery, iSorters, ppSorters, tTermSetup ); break;
default:                              sphDie ( “INTERNAL ERROR: unknown matching mode (mode=%d)”, pQuery->m_eMode );
       }

ISphTokenizer * pTokenizer
// 用作解析的配置信息,例如字符集,切詞規則(n-gram)
// 包括同義詞,過濾詞

1.      pResult = pIndex->Query ( pTokenizer, pDict, &tQuery );
{
ISphMatchSorter * pTop = sphCreateQueue ( pQuery, m_tSchema, sError );(
pTop=newCSphMatchQueue<matchrelevancelt_fn>      ( pQuery->m_iMaxMatches, bUsesAttrs ); //選擇排序規則
)
2.      if ( QueryEx ( pTokenizer, pDict, pQuery, pResult, pTop ) )
3.      bool bRes = MultiQuery ( pTokenizer, pDict, pQuery, pResult, 1, &pTop );
4.      case SPH_MATCH_BOOLEAN:          bMatch = MatchBoolean ( pQuery, pResult, iSorters, ppSorters, tTermSetup );
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章