这是译文,原文地址:http://xapian.org/docs/sorting.html

搜索结果的排序

简介

默认情况下,Xapian按相关性递减的原则来排序搜索结果.然而,它也可以让搜索结果按其他指标,或其他指标和相关性的混合排序。 如果两个搜索结果从排序标准来判断是相同的分值,那他们的返回顺序就取决于它们的文档ID了.默认情况下,他们会按文档ID的升序排序(这样,一个较小的文档ID就会排前面),但可以设置为降序排列enquire.set_docid_order(enquire.DESCENDING);。如果你无所谓,你可以告诉Xapian随便使用任何一种排序都有序enquire.set_docid_order(enquire.DONT_CARE);。

按相关性排序

默认情况下Xapian使用的是BM25加权公式,它有许多参数可以设置。其中的部分参数我们使用默认值,在应付一般的工作时,它们工作得很好。这些参数的最佳值取决于数据被索引的方式和要运行的查询的类型,所以你也许可以改善一下,通过调整这些值来使搜索系统更有效,但它是一个繁琐的过程,人们通常懒得这么干。 去BM25文件了更多的细节。 其他权重方式包括TradWeight和BoolWeight. TradWeight实现了原来的概率加权公式,基本上是BM25的一种特殊情况(它就是BM25在K2 = 0,K3= 0,b = 1和min_normlen = 0的加权,只不过用一个常量线性缩放鸟)。 BoolWeight给所有文档,因此排序完全取决于其他因素。 您也可以实现自己的权重系统,只要用一个数值的形式来量化匹配的条件的(减去不匹配的条件),再考虑一些跟查询term无关的统计资料(比如说,标准化文件长度),就大功靠成鸟。 例如,这里有一个“几何匹配法” - 每个匹配就给一分: 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(Xapian::BoolWeight())实现,同时还要使用 enquire.set_docid_order(Xapian::Enquire::DESCENDING);如果你想最老的文档在前面,你可以用: enquire.set_docid_order(Xapian::Enquire::ASCENDING).很难说清楚有什么内在原因使这种技术不能用于按其他东东排序,通常我们总是最后索引新文章罢了,而最后索引的文章拥有较大的文档ID.嗯,其实我们只是在按文档ID排序而已.

按Value排序

你可以让文档通过比较某一特定Value来决定排序先后.请注意,在比较中是按字节序列来比较的,所以1 <10 <2。如果你要编码value,(使它按数值方式比较),请在索引时用Xapian::sortable_serialise()来编码Value;这同时适用于整数和浮点值:

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

有3种方法用来用来决定Value如何进行排序,而这取决于在排序里你是否使用和想如何使用相关性:

  • Enquire::set_sort_by_value(),相关性完全并不影响排序。
  • Enquire::set_sort_by_value_then_relevance()相关性只是用来决定在Value相同时文档如何排序.
  • Enquire::set_sort_by_relevance_then_value()指定了文档先按相关度排序,相关度相同时再按文档的Value排序(相同相关度:要的是权重也相同,而不只是用百分比表示的分数相同)。这种方法对于默认的BM25权重方式基本没啥用,因为默认的BM25权重方式几乎不会给不同的文档指定相同的分数.

按生成值排序

为了做到更精细的排序,Xapian正在考虑允许您从Xapian::Sorter继承一个子类,这个子类的函数可以用来为每个匹配的文件生成一个值,这个值就用来决定排序。这个函数针对每个匹配的文档顶多调一次,然后生成一个排序值,这个排序值会被按字节序来比较,以决定排序。 系统内置了一个标准的子类Xapian::MultiValueSorter,,它允许指定由文档的多个Value来决定文档的排序(当文档的第一个value相同时,第二个Value决定排序,第二个Value相同时,第3个Value决定排序,以此类推)。 Xapian::Sort也可以衍生出子类,以提供按地理距离排序的功能。子类可以用一个坐标(比如[纬度,经度])来代表用户的位置,然后用存储在文档中的座标来计算出跟用户之间的距离,使跟用户位置最近的结果得到更高的分数。