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
xapian的使用的更多相关文章
- xapian安装
xapian安装:$ su enter your root password # rpm -ivh http://rpm.eprints.org/rpm-eprints-org-key-1-1.noa ...
- xapian倒排索引的归并流程
Xapian的检索流程和大部分搜索系统都一样,就先从倒排表抽取候选文档,然后结合其他信息进行排序,取top文档作为搜索结果,具体流程如下: 图1 xapian搜索流程 具体流程 在terms中找到do ...
- xapian搜索系统存储结构解读
Xapian的database是所有用于检索的信息表的集合,以下的表是必需的: posting list table 保存了被每一个term索引的document,实际上保存的应该是document在 ...
- Xapian索引-文档检索过程分析之匹配百分比
本文属于文档检索过程分析的一部分,重点分析文档匹配百分比(percent)的计算过程. 1 percent是什么? 我们之前分析的检索demo: Xapian::Query term_one = Xa ...
- Xapian索引-文档检索过程分析
本文是Xapian检索过程的分析,本文内容中源码比较多.检索过程,总的来说就是拉取倒排链,取得合法doc,然后做打分排序的过程. 1 理论分析 1.1 检索语法 面对不同的检索业务,我们会有多种检索 ...
- Xapian的内存索引-添加文档
本文主要记录Xapian的内存索引在添加文档过程中,做了哪些事情. 内容主要为函数执行过程中的流水线. demo代码: Xapian::WritableDatabase db = Xapian::In ...
- Xapian的内存索引
关键字:xapian.内存索引 xapian除了提供用于生产环境的磁盘索引,也提供了内存索引(InMemoryDatabase).内存索引.我们可以通过观察内存索引的设计,来了解xapian的设计思路 ...
- Xapian使用入门
关键字:搜索引擎.Xapian 一篇拖了两三年的入门总结文章,今天发出来,一方面是自己的总结,另一方面是给自己和他人的备忘.读者需要对搜索引擎有初步了解,譬如了解倒排.term.doc.相似度打分等概 ...
- Xapian构建索引说明
Reference: http://www.totogoo.com/article/115/xapian-desc.html Xapian与开源 Xapian的官方网站是http://www.xapi ...
- 全文搜索引擎Xapian
安装过程 安装xapian-core wget http://oligarchy.co.uk/xapian/1.0.13/xapian-core-1.0.13.tar.gztar zxvf xapia ...
随机推荐
- java 多线程总结篇3之——生命周期和线程同步
一.生命周期 线程的生命周期全在一张图中,理解此图是基本: 线程状态图 一.新建和就绪状态 当程序使用new关键字创建了一个线程之后,该线程就处于新建状态,此时它和其他的Java对象一样,仅仅由Jav ...
- POJ 1236 Network of Schools(tarjan求强连通分量+思维)
题目链接:http://poj.org/problem?id=1236 题目大意: 给你一个网络(有向图),有两个任务: ①求出至少同时需要几份副本可以使得整个网络都获得副本 ②至少添加多少信息表(有 ...
- Ubuntu 搭建ELK
一.简介 官网地址:https://www.elastic.co/cn/ 官网权威指南:https://www.elastic.co/guide/cn/elasticsearch/guide/curr ...
- C#设置窗体中的窗体随主窗体大小变化而变化
form2 f=new form2(); f.Size=this.Size; f.Location=this.Location; f.showdialog(); 作者:耑新新,发布于 博客园 转载请 ...
- android拾遗——AlarmManager的使用
AlarmManager的作用文档中的解释是:在特定的时刻为我们广播一个指定的Intent.简单的说就是我们设定一个时间,然后在该时间到来时,AlarmManager为我们广播一个我们设定的Inten ...
- 转发:RocketMQ与kafka的对比
淘宝内部的交易系统使用了淘宝自主研发的Notify消息中间件,使用Mysql作为消息存储媒介,可完全水平扩容,为了进一步降低成本,我们认为存储部分可以进一步优化,2011年初,Linkin开源了Kaf ...
- pyspider 在ubuntu上安装失败怎么搞?
pyspider 是一个非常不错的爬虫框架,在ubuntu上安装时报错误: 很明显pycurl的问题,pycurl没安装成功 pycurl 安装错误解决办法: sudo apt-get install ...
- day4 计算器
作业:计算器开发 (1)实现加减乘除及拓号优先级解析: (2)用户输入 1 - 2 * ( (60-30 +(-40/5) * (-9-2*5/-3 + 7 /3*99/4*2998 +10 * 56 ...
- Mongoose关于当天日期的查询
参考:https://blog.csdn.net/difffate/article/details/70312894 Ant Design Pro中,有关于日期的查询条件,但日期是以数字表示的 Req ...
- ubuntu16.04 安装symfony3.3.11 碰到的问题:extension dom is required | oops an error occurred 500
问题1:Uncaught exception 'RuntimeException' with message 'Extension DOM is required' 解决:sudo apt-get i ...