现在的位置: 首页 > 综合 > 正文

字段排序

2014年07月12日 ⁄ 综合 ⁄ 共 2106字 ⁄ 字号 评论关闭

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


2. 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方法来注入自己的加分器。

3. 当然,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的比较是以字符串来进行比较的。

抱歉!评论已关闭.