sphinx简析

来源:互联网 发布:留学回国证明 知乎 编辑:程序博客网 时间:2024/05/22 10:40
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 );
原创粉丝点击