sphinx简析

来源:互联网 发布:写脚本的软件 编辑:程序博客网 时间:2024/05/01 11:03

CSphSource 数据源

CSphSource_XMLPipe2-XML文件获取数据

CSphSource_SQL-SQL(MySQL)获取数据

 

 

CSphIndex 索引器

派生类CSphIndex_VLN

// 索引过程

virtual int Build ( CSphDict * pDict,

const CSphVector<CSphSource*> & 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是系统的配置文件。其它则为索引文件。

l        Spi     文件:保存WordId及指向此WordId对应的文档信息在spd文件的指针。Spi文件在检索程序启动时完全加载入内存。Spi文件是分块的,块内排序,块之间也排序。分块的目的应该是为了快速检索到WordId,因为Spi中的WordId是变长压缩的,索引需要先在块级别做二分定位,再在快内解压缩查找。

文件结构,每块中结构,wordId实际存储的是差值

WordId

SpdFilePointer

DocNum

HitNum

l        Spd文件:

文件结构

DocID

[DocInfo]

HitFilePointer

FieldNum

HitNum

l        Spp文件

文件结构

HitPos

l        Spa文件:存储DocInfo的文件,检索程序启动时会把此文件加载如内存,sphinx可以指定DocInfo的存储方式,

1.        存储到spd文件中(InLine

2.        另外单独存储。指定此,就会生成spa文件

文件结构:

DocId

DocInfo

l        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.. CSphWordHitCSphWordHitCSphWordHit串接

dHitBlocks.Add( cidxWriteRawVLB ( fdTmpHits.GetFD(), dHits, iHits, NULL, 0, 0 ) );//

GetIndexFileName("tmp1") Hits流写入tmp1文件。临时文件

不论重复,不论字段

 

dBins[i]->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<false>>      ( 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 );