xapian note 01

[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)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Solr&ElasticSearch原理及应用 一、综述 搜索 http://baike.baidu.com/it...
    楼外楼V阅读 7,432评论 1 17
  • 依稀记得15年8月北京之行,夜晚在幽静的山谷里躺在凉席上看星星的情景。好多颗流星划过天际,划出美丽的身影。那时才...
    kitty99阅读 340评论 0 0
  • 落丛勇为草中英,入口偏能洗涤烦。一撮春色见日月,半铛泉水煮山川!
    李炼阅读 234评论 0 1