xapian-xunsearch的后端

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

先看一下执行过程: 数据库


检索相关:
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的时候仍是要注意一些东西的。
相关文章
相关标签/搜索