xapian的使用

1、先来看一下Xapian的介绍:

Xapian的官方网站是http://www.xapian.org,这是一个非常优秀的开源搜索引擎项目,搜索引擎其实只是一个通俗的说法,正式的说法其实是IR(Information Retrieval)系统。Xapian的License是GPL,这意味着允许使用者自由地修改其源码并发布之。Xapian的中文资料非常少,可以说现在互联网上连一篇完整详细的Xapian中文介绍文档,更别说中文API文档了。


Xapian由C++编写,但可以绑定到Perl, Python, PHP, Java, Tcl, C# 和Ruby甚至更多的语言,Xapian可以说是STL编程的典范,在这里您可以找到熟悉的引用计数型智能指针、容器和迭代器,甚至连命名也跟STL相似,相信一定能引起喜好C++和STL的你的共鸣(实际上,很少C++程序员完全不使用STL)。


注:

更详细的介绍请参考http://www.162cm.com/p/xapian-learning.html

自己编译参考请参考http://blog.csdn.net/visualcatsharp/article/details/4096639

当然你也可以直接下载我自己编译的版本:(包含在测试项目中,下载地址:)

http://download.csdn.net/detail/zengraoli/5791047


二、使用Xapian的一个例子(神马介绍都是浮云,能用起来才是王道)

// writedatabase.cpp : 定义控制台应用程序的入口点。
//

#include "../xapian.h" 
#include <iostream>
using namespace std;


#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "../xapian-lib/zdll.lib")
#pragma comment(lib, "../xapian-lib/libapi.lib")
#pragma comment(lib, "../xapian-lib/libapi.lib")
#pragma comment(lib, "../xapian-lib/libbackend.lib")
#pragma comment(lib, "../xapian-lib/libcommon.lib")
#pragma comment(lib, "../xapian-lib/libexpand.lib")
#pragma comment(lib, "../xapian-lib/libflint.lib")
#pragma comment(lib, "../xapian-lib/libflintbtreecheck.lib")
#pragma comment(lib, "../xapian-lib/libinmemory.lib")
#pragma comment(lib, "../xapian-lib/liblanguages.lib")
#pragma comment(lib, "../xapian-lib/libmatcher.lib")
#pragma comment(lib, "../xapian-lib/libmulti.lib")
#pragma comment(lib, "../xapian-lib/libnet.lib")
#pragma comment(lib, "../xapian-lib/libquartz.lib")
#pragma comment(lib, "../xapian-lib/libquartzbtreecheck.lib")
#pragma comment(lib, "../xapian-lib/libqueryparser.lib")
#pragma comment(lib, "../xapian-lib/libremote.lib")
#pragma comment(lib, "../xapian-lib/libtest.lib")
#pragma comment(lib, "../xapian-lib/libunicode.lib")


#define INDEX_PATH "..\\index_data"


int main(int argc, char **argv)
{
	try
	{
		// 创建或者打开一个可读写的数据库
		Xapian::WritableDatabase db(INDEX_PATH, Xapian::DB_CREATE_OR_OPEN);
		// 分词器
		Xapian::TermGenerator indexer;
		string para;
		int flag = 0;
		while (flag++ < 8)
		{
			string line;
			if (cin.eof())
			{  
				if (para.empty()) break;
			}
			else
			{
				getline(cin, line);
			}
			if (line.empty())
			{
				if (!para.empty())
				{
					// 生成一个文档
					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;
			}
		}  

		db.flush();
	}
	catch (const Xapian::Error &e)
	{
		cout << e.get_description() << endl;
		exit(1);
	}
}

说说上面程序核心部分的意思:

         以DB_CREATE_OR_OPEN方式打开INDEX_PATH路径下的数据库(这种方式是,不存在则创建出来,存在就直接追加);

         在Xapian中也有这样一个概念,所有的Xapian操作都是围绕数据库来的,在索引建立的时候,所有文档(Document)都会被放入数据库中

         所以我们下一步是来创建文档:Xapian::Documentdoc;假如从控制台输入的数据不为空,那么para是有数据的(控制台通过判断当前输入是否为empty,即空行的情况),我们去设置这个文档的内容:doc.set_data(para);

这样我们的文档里边是存在内容的了,那么我们需要通过分词器去为我们识别每一个词indexer.set_document(doc);,用indexer.index_text(para);设置我们的索引text(对于这个函数的说明是这样的):

    /** Index some text in a std::string.
     *
     * @param weight	The wdf increment (default 1).
     * @param prefix	The term prefix to use (default is no prefix).
     */

Xapian默认是通过判断空格来区分每一个词的,所以这么设置之后,假若文档中有N个空格,那么单词数就有N+1个。

最后一步,要把这个已经分好词的文档,放到数据库中db.add_document(doc);


这样之后,我们的数据库就有数据了,这里我的输入是:



下面来看看,怎样对刚才数据库中的这几条语句,做检索:

// search.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "../xapian.h" 
#include <iostream>
using namespace std; 

#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "../xapian-lib/zdll.lib")
#pragma comment(lib, "../xapian-lib/libapi.lib")
#pragma comment(lib, "../xapian-lib/libapi.lib")
#pragma comment(lib, "../xapian-lib/libbackend.lib")
#pragma comment(lib, "../xapian-lib/libcommon.lib")
#pragma comment(lib, "../xapian-lib/libexpand.lib")
#pragma comment(lib, "../xapian-lib/libflint.lib")
#pragma comment(lib, "../xapian-lib/libflintbtreecheck.lib")
#pragma comment(lib, "../xapian-lib/libinmemory.lib")
#pragma comment(lib, "../xapian-lib/liblanguages.lib")
#pragma comment(lib, "../xapian-lib/libmatcher.lib")
#pragma comment(lib, "../xapian-lib/libmulti.lib")
#pragma comment(lib, "../xapian-lib/libnet.lib")
#pragma comment(lib, "../xapian-lib/libquartz.lib")
#pragma comment(lib, "../xapian-lib/libquartzbtreecheck.lib")
#pragma comment(lib, "../xapian-lib/libqueryparser.lib")
#pragma comment(lib, "../xapian-lib/libremote.lib")
#pragma comment(lib, "../xapian-lib/libtest.lib")
#pragma comment(lib, "../xapian-lib/libunicode.lib")


#define INDEX_PATH "..\\index_data"


int main()
{
	try
	{
		//打开数据库
		Xapian::Database db(INDEX_PATH);
		// Start an enquire session.
		// 生成查询会话
		Xapian::Enquire enquire(db);
		string query_string("zengraoli");
		Xapian::QueryParser qp;
		qp.set_database(db);
		qp.set_stemming_strategy(Xapian::QueryParser::STEM_SOME);
		// 解析查询条件
		Xapian::Query query = qp.parse_query(query_string);
		cout << "Parsed query is: " << query.get_description() << endl;
		// 把解析后的查询条件放入查询会话
		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);
	}
	return 0;

}

search程序核心部分:

首先打开数据库,生成一个临时会话(相当于数据库连接中的一条管道),设置我要查询的单词(这里是“zengraoli)

再来生成一个查询分析器,设置查询分析器中对应的数据库(db),设置它的返回策略(这里选择的是部分:Xapian::QueryParser::STEM_SOME)

设置查询条件,也就是上面的单词;

输出我们的查询条件看看:query.get_description()

在刚才的临时会话(管道)中,设置我们上面的查询条件;

Xapian::MSet matches用来得到从数据库中返回的所以匹配的条目;

matches.get_matches_estimated()matches.size()分别是显示出匹配的条目和大小;

我们需要一个迭代器,从匹配的条目中,逐个输出到控制台中:

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";
		}

i.get_rank()0开始,我们必须+1,才能和使用者的三观保持一致。i.get_percent()是匹配条目的相似度(在这里是按所占文档的权重排列)的信息,;i.get_document().get_data()返回含有匹配单词的文档内容。


好了,下面我们看看结果:




测试数据,在这里是很少的,仅仅有四条doc

可以的话,下次测试多一些的数据,看看速度如何。



整个测试项目下载地址:

http://download.csdn.net/detail/zengraoli/5791047

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
Python Xapian(简称xapian)是一个用于全文搜索和信息检索的开源工具库。它提供了Python语言的接口,使得我们可以方便地在Python环境中使用xapian的功能。 xapian是一种基于倒排索引的搜索引擎。它的主要特点是快速、可扩展,以及支持多种语言。我们可以利用xapian来创建和维护一个倒排索引库,然后在这个库上进行全文搜索和信息检索。 使用xapian,我们可以将一个文本集合中的文档添加到索引库中。这个索引库可以包含多个字段,每个字段可以是不同的文本类型(例如标题、正文、作者等)。然后,我们可以使用查询语句在这个索引库中进行搜索。xapian支持多种查询类型,例如布尔查询、短语查询、通配符查询等。 除了基本的全文搜索,xapian还提供了一些高级功能。例如,我们可以使用xapian来计算查询和文档之间的相关性得分,从而对搜索结果进行排序。xapian还支持结果分页、结果高亮显示等功能,使得搜索结果更易于阅读和理解。 使用Python Xapian,我们可以在Python程序中轻松地集成全文搜索和信息检索功能。它可以应用于各种场景,例如网站搜索引擎、文档管理系统、邮件分类等。通过合理使用xapian的功能,我们可以帮助用户快速准确地找到他们所需的信息,提高用户体验和效率。 总之,Python Xapian是一个功能强大、易于使用的全文搜索和信息检索工具库。它提供了丰富的功能和灵活的接口,可以满足不同应用的需求。无论是初学者还是专业开发人员,都可以利用xapian来构建高效的搜索和检索系统。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值