美文网首页
xapian note 01

xapian note 01

作者: 游同学_4907 | 来源:发表于2018-07-25 15:43 被阅读0次

[1]. Index

xapian建立索引,参考https://github.com/xapian/xapian-docsprint/blob/master/code/c%2B%2B/index1.cc

主要涉及类:

数据库类 WritableDatabase

文档类 Document

Term生成工具类 TermGenerator

主要使用TermGenerator将输入内容转化为term并index,存放Document类数据中,实际保存的是Document类数据。Document分为两部分内容,一是原始数据,通过Document自己的方法添加;二是posting/index数据,通过TermGenerator添加。

TermGenerator基本工作过程:

1) set_document:设置目标doc。

2) index_text:将输入内容parse成term并添加。代码在termgenerator_internal.cc中。主要原理是将输入的内容先parse,然后逐个记录下位置,wdf,录入进doc中,如:

doc.add_posting(prefix + term, ++termpos, wdf_inc);   //termgenerator_internal.cc:258

term可以添加prefix;termpos即term在输入内容中的位置;wdf_inc为本次添加term的frequency权重(通常是1)

根据不同的策略添加为posting或单纯term,以及是否使用stem模式等等。

*) termpos 为Document类内部变量,连续的调用index_text方法会连续增加termpos。有时候想区分不同field的数据,可以在不同field的index_text之间插入隔断,方法为increase_termpos,默认是100位。原理即增加Document类中的termpos,下一次index_text即产生隔断。

*) Document类有docid,但往往输入数据有原始编号,可以将原始编号map进Document类中方便使用和管理。方法是add_boolean_term(idterm),idterm为原始编号。原理是为Document增加一个wdf为0的term,这样既能被识别到又不会对index计算产生实际影响。参考api中的说明。

写入数据库:使用WritableDatabase类的replace_document方法,添加/替换一个文档。replace_document可以指定unique_term,这是前面的添加的booleam_term就派上用场了。使用替换的原因是防止同一个doc被重复添加。

[2]. Search

index之后就可以检索,参考https://github.com/xapian/xapian-docsprint/blob/master/code/c%2B%2B/search1.cc

核心为两部分,QueryParser解析query,Enquire实现检索。

检索主要由Enquire类的get_mset(offset, pagesize)实现,返回结果中第offset ~ offset+pagesize顺位的结果。返回MSet类。MSet主要方法:mset.begin(); mset.end() 返回MSetIterator类用于遍历。对于MSetIterator类变量m,*m取结果的docid,m.get_rank()取结果的顺位,m.get_document()取结果的文档。

[3].facet

分面搜索facet值得是对于文档数据,在index的字段外,额外保存一些信息,不参与index,但是可以用于检索之后的统计和限定。例如搜索商品,通过关键词检索之后,引擎出了展示靠前的若干个商品,还能展示涉及的各个品牌都分别有多少商品。

参考 xapian文档关于facet的介绍index_facets

  search_facets

实现方法主要在于Document类中的set_value(),get_value()方法,以及ValueCountMatchSpy类。

index时,每个doc均可添加若干value slot,每个slot存一类信息。

ValueCountMatchSpy作用是在search返回mset过程中观测value。search时,新建ValueCountMatchSpy类spy,定义时指定slot,如

Xapian::ValueCountMatchSpy spy(1);

即指定观测slot 1上各个文档的value。将spy绑定到enquire上即可。如果需要分面搜索,使用get_mset时需要指定checkatleast,即

get_mset(offset, pagesize,checkatleast)

因为返回的mset一般只是整个March_Set中靠前的少部分结果,但是spy希望观测到较多的数据,因此可指定checkatleast值,表示至少要观测March_set中这么多的文档。如果checkatleast小于pagesize会取pagesize。

通过ValueCountMatchSpy的方法统计结果。如下:

for (Xapian::TermIterator facet = spy.values_begin();  facet != spy.values_end();   ++facet)

将spy中所有的facet value遍历,对于每个facet,调用 facet.get_termfreq() 统计该facet的频次。

注意这个遍历对于value而言是无序的(取决于spy存放value的顺序),对于有序的value类型(如数字)需要使用sortable_serialise。(TODO)

相关文章

网友评论

      本文标题:xapian note 01

      本文链接:https://www.haomeiwen.com/subject/pywpmftx.html