Xapian介绍
----------
1. 简单介绍
Xapian 是一个开源的搜索引擎库,是用C++来编写的,准许GPL协议(http://www.opensource.org/licenses/gpl-license.php),它现在可以与Perl,python,PHP,Java等语言来绑定使用。
和Lucene一样,Xapian只是一个搜索引擎工具库,用户可以在其上自己扩展其适合的应用,它是基于概率模型来做为查询分数计算的基本,当然,它还提供了丰富的Boolean查询功能。
如果你想把Xapian使用在你的网站上,你可以使用Xapian的一个套装,Omega可以满足你的大部分需求,当然它的扩展性还是不错的。
目前Xpian的稳定版本是1.2.10,
2. 功能介绍
下面是一些Xpian的主要功能点:
- × 开源,基于GPL协议
- × 支持Unicode,存储索引数据也是用UTF-8
- × 可移植性,可以运行在Linux,Mac Os X, Windows系统上
- × 支持多种语言的绑定,现在有Perl,python,java,PHP,C#等
- × 以概念模型为查询分数计算基础
- × 相关度的反馈,Xapian能够基于用户的查询条件来返回与其相关的词组或者文档,或者一类相关的文档
- × 词组与近似词查询,用户的查询条件可以指定词组中词的出现顺序,出现次数等条件
- × 支持Boolean查询,如"A NOT B",Boolean查询结果的排序是基于概率模型,
- × 支持词要的查询
- × 支持前缀查询,如Xap*
- × 支持同义词查询,
- × 支持基于用户查询条件的拼写检测
- × 支持分面搜索。http://xapian.org/docs/facets
- × 支持大于2GB的数据文件
- × 与平台独立的索引格式,你可以在linux下建立索引,再把索引文件复制到windows机器上,也能查询
- × 支持同步更新与查询,新文档可以立即被查询到
Xapian还提供了一个CGI查询应用,Omega, 它有如下特点
- × 索引格式支持HTML,PHP,PDF,PostScript等,也可以通过它的filters来自定义索引格式,
- × 可以使用Perl DBI module来支持对于SQL的索引,如MySql,PstgreSQL,SQLite,Oracle等
- × CGI有不错的可扩展性。可以支持XML与CSV的定制输出,
3. 一个例子
3.1 linux下的安装
在ubuntu或者debian下,可以用
$ sudo apt-get install python-xapian
$ sudo apt-get install libxapian-dev
来安装,或者从源代码编译安装,./configure, make ,make install
3.2 索引建立
#include <xapian.h> // 头文件
#include <iostream>
#include <string>
#include <cstdlib> // For exit().
#include <cstring>
using namespace std;
int
main(int argc, char **argv)
try {
if (argc != 2 || argv[1][0] == '-') {
int rc = 1;
if (argv[1]) {
if (strcmp(argv[1], "--version") == 0) {
cout << "simpleindex" << endl;
exit(0);
}
if (strcmp(argv[1], "--help") == 0) {
rc = 0;
}
}
cout << "Usage: " << argv[0] << " PATH_TO_DATABASE\n"
"Index each paragraph of a text file as a Xapian document." << endl;
exit(rc);
}
// Open the database for update, creating a new database if necessary.
// 创建或者打开一个可读写的数据库
Xapian::WritableDatabase db(argv[1], Xapian::DB_CREATE_OR_OPEN);
// 分词器
Xapian::TermGenerator indexer;
Xapian::Stem stemmer("english");
indexer.set_stemmer(stemmer);
string para;
while (true) {
string line;
if (cin.eof()) {
if (para.empty()) break;
} else {
getline(cin, line);
}
if (line.empty()) {
if (!para.empty()) {
// We've reached the end of a paragraph, so index it.
// 生成一个文档
Xapian::Document doc;
doc.set_data(para); // 定义文档数据,这些数据对于用户来说是不透明的,用户可以在这里定义文档的一些属性,或URI,路径等信息
// 设置文档,分词
indexer.set_document(doc);
indexer.index_text(para);
// Add the document to the database.
// 把文档加入数据库
db.add_document(doc);
para.resize(0);
}
} else {
if (!para.empty()) para += ' ';
para += line;
}
}
// Explicitly commit so that we get to see any errors. WritableDatabase's
// destructor will commit implicitly (unless we're in a transaction) but
// will swallow any exceptions produced.
db.commit();
} catch (const Xapian::Error &e) {
cout << e.get_description() << endl;
exit(1);
}
3.3 查询
#include <xapian.h>
#include <iostream>
#include <string>
#include <cstdlib> // For exit().
#include <cstring>
using namespace std;
int
main(int argc, char **argv)
try {
// We require at least two command line arguments.
if (argc < 3) {
int rc = 1;
if (argv[1]) {
if (strcmp(argv[1], "--version") == 0) {
cout << "simplesearch" << endl;
exit(0);
}
if (strcmp(argv[1], "--help") == 0) {
rc = 0;
}
}
cout << "Usage: " << argv[0] << " PATH_TO_DATABASE QUERY" << endl;
exit(rc);
}
// Open the database for searching.
//打开数据库
Xapian::Database db(argv[1]);
// Start an enquire session.
// 生成查询会话
Xapian::Enquire enquire(db);
// Combine the rest of the command line arguments with spaces between
// them, so that simple queries don't have to be quoted at the shell
// level.
string query_string(argv[2]);
argv += 3;
while (*argv) {
query_string += ' ';
query_string += *argv++;
}
// Parse the query string to produce a Xapian::Query object.
// 生成查询解析器
Xapian::QueryParser qp;
Xapian::Stem stemmer("english");
qp.set_stemmer(stemmer);
qp.set_database(db);
qp.set_stemming_strategy(Xapian::QueryParser::STEM_SOME);
try
// 解析查询条件
Xapian::Query query = qp.parse_query(query_string);
cout << "Parsed query is: " << query.get_description() << endl;
// Find the top 10 results for the query.
// 把解析后的查询条件放入查询会话,
enquire.set_query(query);
// 得到查询结果
Xapian::MSet matches = enquire.get_mset(0, 10);
// Display the results.
cout << matches.get_matches_estimated() << " results found.\n";
cout << "Matches 1-" << matches.size() << ":\n" << endl;
// 得到查询结果
for (Xapian::MSetIterator i = matches.begin(); i != matches.end(); ++i) {
cout << i.get_rank() + 1 << ": " << i.get_percent() << "% docid=" << *i
<< " [" << i.get_document().get_data() << "]\n\n";
}
} catch (const Xapian::Error &e) {
cout << e.get_description() << endl;
exit(1);
}
4. 参考
http://xapian.org/