xapian-xunsearch的后端

原创
2013/10/25 10:26
阅读数 1.7K

Xapian 是一款开源的C++信息检索系统,内部系统试用了xunsearch,因此稍微了解了一下“虾片”的机制

先看一下执行过程:


检索相关:
Xapian::Database 用于读取索引。
Xapian::Enquire 提供检索服务,与Xapian::Database配合使用
Xapian::QueryParser 查询语句解析器
Xapian::Query 查询语句
Xapian::MSet 检索返回的匹配结果记录集

建索引相关:
Xapian::WritableDatabase 用于建立索引。
Xapian::TermGenerator 非常简单的切词、建索引器,不是必须使用的,可用其他替代,但是提供了一些帮助函数,非常好用。

共用:
Xapian::Document 文档的抽象。
Xapian::SimpleStopper 停用词
Xapian::Error 异常类,.get_description()获取详细信息。

后端相关:
Xapian::Database::Internal     每个后端都要实现

Database,也可以称为Index
Database类型
- auto
     - 
- brass
     - 当前开发中的后端,并将作为1.4.x版本起的默认后端
- chert
     - 1.2.x的默认后端,支持增量修改、单写者+多读者的并发。
     - 高效且可扩展
- flint
     - 1.0.x的默认后端,类chert
- inmemory
     - 全内存的database,可用于建立临时小database
- quartz
     - 1.0的默认后端,1.1.0后移除 

文档
- 粒度
     - RMDB:表中的一条记录
     - html:一个html文件/一个标签
- 表示方式
     - 32位 Document ID
     - 3个组分
          - 数据data
               - 只存储,不分析其内容,通常用于结果的返回
               - 是文档的部分/全部数据
          - 词集terms
               - 基本的查询单元
          - 值域集values

分词器
- xapian没有Field的概念,通过在每个词前加前缀来标识
需要注意的是,在Xapian中,如果你在索引的时候使用了TermGenerate来进行分词,那在查询的时候一定要使用QueryParser来对查询条件进行解析

索引
一些限制:
- Term Length:一个词限制在256个字节内,
- Document Data:一个data区不能大于100MB,默认是8KB
- Document value:和一个data区的限制是一样的,但一般建议value不要太大
- Document ID: 当前范围是32bit,大概在43亿左右,文档删除的ID号不会被重新利用,除非你对数据库进行compact
- B-tree block number: 目前支持最大为32bit个块
- OS file size:所有操作系统对于单个文档的限制对于Xapian都适用,如ext4对于单个文件的大小为16TB,
- Document length:文档长度的存储限制为unsigned 64bit

索引格式
- Xapian有多种数据库格式 

分面搜索(faceted search)
- 将搜索结果进行聚类处理

并行读写操作
- 写
     -  数据库只支持单个数据库写对象存在
     -  也就是说在创建一个DataBaseWritable对象的时候,会对数据库进行加锁,如果另一个写数据库对象再去写这个数据库时,会出现DatabaseLockError错误。
- 读
     -  但是多个读对象是同时存在于同一个数据库。
- 更新
     -  读/写操作隔离
         -  当打开一个数据库准备进行读操作时,会创建一个找开数据库的镜像,这样有写操作时,读对象是不可见的,除非读对象运行reopen()操作。
     - 限制
          -  现在的Xapian多版本同步还是有一些限制的,特别是当数据库有两个版本同时存在时,也就是说有多个读,一个写数据库操作时,当写数据库只修改了数据库,运行了一次commit时,是没问题的,但是当写数据库又运行了第二次commit时,读数据库操作会收到了一个Xapian::DatabaseModifiedError,在这种情况下,读数据库操作要更新其数据库的镜像版本,使用reopen()操作,这个要在编程上注意一下。

数据同步
同时支持数据库的复制,而且只复制那些变更过的索引数据,这样可以使用数据冗余,达到负载均衡的目的 


常见问题
DatabaseLockError错误
- 数据库只支持单个数据库写对象存在,也就是说在创建一个DataBaseWritable对象的时候,会对数据库进行加锁,如果另一个写数据库对象再去写这个数据库时,会出现DatabaseLockError错误
- 但是多个读对象是同时存在于同一个数据库。

DatabaseModifiedError错误
- 当打开一个数据库准备进行读操作时,会创建一个找开数据库的镜像,这样有写操作时,读对象是不可见的,除非读对象运行reopen()操作。这样读/写操作就隔离了。
- 现在的Xapian多版本同步还是有一些限制的,特别是当数据库有两个版本同时存在时,也就是说有多个读,一个写数据库操作时,当写数据库只修改了数据库,运行了一次commit时,是没问题的,
- 但是当写数据库又运行了第二次commit时,读数据库操作会收到了一个Xapian::DatabaseModifiedError,在这种情况下,读数据库操作要更新其数据库的镜像版本,使用reopen()操作。

- 多线程支持
- Xapian没有显示的支持多线程,为了避免不必要的线程死锁,Xapian没有使用任何全局变量,所以你可以你的多线程应用中放心的使用Xapain对象。
- 但是一些Xapian对象内部是有关联的,如Xapian::Database::get_document(),返回的对象Xapian::Document对象内部保存了一个指向DataBase的一个引用,所以它不适合在多线程中使用,所以在多线程中使用Xapian的时候还是要注意一些东西的。
展开阅读全文
打赏
0
3 收藏
分享
加载中
更多评论
打赏
0 评论
3 收藏
0
分享
返回顶部
顶部