1. 分面搜索使用户可以动态的对用户所查询的命中文档进行特定属性的聚合,分面搜索在很多地方都有应用,特别昌电子商场中,用户输入一个查询条件,服务器返回这个查询所命中的文档的分类信息,如用户查询“电脑”,那服务器返回命中“电脑”这个关键词的所有文档,并且对这些文档进行类型的聚类,如平板电脑、笔记本电脑、台式机等分类都有出现“电脑”这个词,这种聚类是多维度的,可能这些命中的文档属于不同的商家,那同时也会对商家进行聚类。总的来说,Faceted search的目标是为用户提供筛选的依据,以其来帮助用户更快的找到自己想要的东西。
它的优点有:
- 高度的信息整合功能:用户可以看到所查询信息的整合后的情况,不是平面的信息,而是多维的信息
- 结果的可预测性:用户在点击某一个分类的时候可以知道这个分类命中了多少个结果
- 没有选择层次的限制:用户可以以不同的添加与删除不同的聚合类别限制
2. 对于Xapian中每一个文档,都有一些values与之对应,你可以把要聚类的字段值放入这些值中,并且给出一个唯一的slot号,使用Xapian::Document::add_value()方法来做,例如你有一个图书数据库,你可以把“price"放在slot
0的位置,"author"放在slot 1的位置,”publisher“放在slot 2的位置,"publication type"放在slot 3的位置,这样在查询的时候,你可以按特定的value进行聚合,如要求命中文档按price在100-200,200-400,400-500,..的图书,要注意的是对于一些数据的字段要用Xapian::sortable_serialize方法来进行编码才能正确的被排序。
3.上面这个图书数据库的例子,你想对price与author进行分面查询,你要对每一个聚类的字段使用
Xapian::Enquire::add_matchspy()方法,把Xapian::ValueCountMatchSpy对象加入其中,它主要是用于计算某一个值在命中文档中出现的频率,一般代码如下:
Xapian::ValueCountMatchSpy spy0(0);
Xapian::ValueCountMatchSpy spy1(1);
Xapian::Enquire enq(db);
enq.add_matchspy(&spy0);
enq.add_matchspy(&spy1);
enq.set_query(query);
Xapian::MSet mset = enq.get_mset(0, 10, 10000);
Xapian::ValueCountMatchSpy spy0(0);
Xapian::ValueCountMatchSpy spy1(1);
Xapian::Enquire enq(db);
enq.add_matchspy(&spy0);
enq.add_matchspy(&spy1);
enq.set_query(query);
Xapian::MSet mset = enq.get_mset(0, 10, 10000);
其中的10000表示要求Xapian至少对10000个文档进行聚类检查,而其中的spy对象保存了分面信息,这些信息可以通过如下方式来得到,
Xapian::TermIterator i;
for (i = spy0.values_begin(); i != spy0.values_end(); ++i) {
cout << *i << ": " << i.get_termfreq() << endl;
}
for (i = spy1.values_begin(); i != spy1.values_end(); ++i) {
cout << *i << ": " << i.get_termfreq() << endl;
}
其中*i表示聚类的值,也就是上面的add_value()方法所添加的值,如果是数据类型,要通过Xapian::sortable_unserialize方法来解码,不然显示可能是混乱,后面的get_termfreq()表示这个聚类命中了几个文档,如price区间在100-200的命中了30个产品。for (i = spy0.values_begin(); i != spy0.values_end(); ++i) {
cout << *i << ": " << i.get_termfreq() << endl;
}
for (i = spy1.values_begin(); i != spy1.values_end(); ++i) {
cout << *i << ": " << i.get_termfreq() << endl;
}