Xapian 学习笔记 3 相关字段的排序

2022-04-27 00:00:00 文档 排序 相关 加分 来做

Xapian 学习笔记 3 相关字段的排序

在Xapina中,命中文档的排序是以文档的相关度降序来做的,当两个文档的相关度一样时,按文档id的升序来做,你也可以通过设置enquire.set_docid_order(enquire.DESCENDING)来把其变成降序,或者设置成不关心文档id的排序enquire.set_docid_order(enquire.DONT_CARE);当然这个排序也可以按其它规则来做,或者其它规则与相关度结合来做,下面我们就分析这两种排序方法。


1. 相关度排序
Xapian默认是以BM25算法来计算每一个文档的分数,而BM25(http://xapian.org/docs/bm25.html)的计算所需要的一些参数值是通过在文档索引的时候统计出来的,当然,有一些参数可以在查询的时候动态设定。
另外一些库自带的加分算法有TradWeight,BoolWeight。其中TradWeight实现了原始的概率模型公式,它是BM25算法的一个特例,只是其中一些参数如k2=0,k3=0和min_normlen=0。而BoolWeight打分器对所有文档的分数都为0,文档的排序由另外一些因素决定。
当然你也可以自定义自己的加分器算法,只要实现Xapian::Weight这个抽象类就可以了,如下是一个同等加分器


class CoordinateWeight : public Xapian::Weight {
public:
CoordinateWeight * clone() const { return new CoordinateWeight; }
CoordinateWeight() { }
~CoordinateWeight() { }


std::string name() const { return "Coord"; }
std::string serialise() const { return ""; }
CoordinateWeight * unserialise(const std::string &) const {
return new CoordinateWeight;
}


Xapian::weight get_sumpart(Xapian::termcount, Xapian::doclength) const {
return 1;
}
Xapian::weight get_maxpart() const { return 1; }


Xapian::weight get_sumextra(Xapian::doclength) const { return 0; }
Xapian::weight get_maxextra() const { return 0; }


bool get_sumpart_needs_doclength() const { return false; }
};


在查询的时候可以调用Enquire的set_weighting_scheme方法来注入自己的加分器。

2. 特定字段值排序
当然,Xapian还可以按用户指定的字段值来排序,如价格,日期等字段,要注意的是所有的排序比较都是基于字符串来做的,所以如果你要对价格进行排序比较,就要把数值类型转换成一个字符串类型,使用Xapian::sortable_serialise()来进行编码,在查询的时候使用Xapian::sortable_unserialise()进行解码,value索引的般代码如下:


Xapian::Document doc;
doc.add_value(0, Xapian::sortable_serialise(price));


所有要排序的字段值都要被加入Docuemnt的value中,个参数是value的slotId号


这里有三种方法来决定文档的排序优先级:
Enquire::set_sort_by_value() 以value为优先进行排序,与相关度无关
Enquire::set_sort_by_value()_then_relevance() 以value为优先,如果value一样的,再以相关度进行排序
Enquire::set_sort_by_relevance_the_value() 以相关度优先排序,再以value排序


在查询的时候要加入不同value的排序代码如下:


// 生成一个多字段的文档key生成器

Xapian::MultiValueKeyMaker *keyMaker = new Xapian::MultiValueKeyMaker();
keyMaker->add_value(0); // 添加文档的第0个slot的值为升序,
keyMaker->add_value(1); // 添加文档的第1个slot的值为升序,如果想用降序,使用keyMaker->add_value(1,true);
enquire.set_sort_by_key(keyMaker,false); // 把key生成器注入到会话中去,第二个参数表示是否降序


当然更加灵活的方法是用户可以实现keyMaker接口,实现自己的key生成器,当然key的比较是以字符串来进行比较的。

3. 参考
http://xapian.org/docs/sorting.html
————————————————
版权声明:本文为CSDN博主「amuseme_lu」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/amuseme_lu/article/details/7620715

相关文章