Xapian实战(二):core concepts

参考资料

core concepts

 

正文

1. 并发性

  xapian不包含任何全局变量,所以多线程编程中,在没有共享资源的情况下可以安全使用xapian。在实际操作中,由于每个线程都可以创建自己的xapian.Database对象,所以这个限制条件完全没有问题。当然如果真的需要在多线程中使用同一个xapian对象,则需要用到mutex的线程锁。

  需要注意的是,有些xapian对象包含了其他对象的引用——例如,xapian.Database.get_document()的结果xapian.Document包含xapian.Database的引用,所以在一条线程中使用xapian.Database,另一条线程中使用xapian.Document对象是不安全的。

 

2. Indexing concepts

2.1 Databases

  几乎所有的xapian操作都围绕着一个xapian的数据库。将文件放入数据库的过程叫做建立索引。存储在数据库中的主要信息是每个术语和对应的文档的映射。数据库还可以存储同义词扩展以及拼写纠错的信息。

2.1.1 Backends

  xapian数据库使用自定义格式保存数据,这样可以保证搜索时的效率;xapian没有使用关系型数据库。xapian有不止一个后台数据库,xapian1.2版本主要的后台数据库为Chert。该数据库在给定地址的文件系统中存储信息。

  xapian允许同时在多个数据库中刚搜索并将结果进行整合的操作。当数据量太大一台机器无法处理时,利用此特性,xapian可以结合远程的数据库来处理并进行搜索。

2.1.2 On-disk databases

  如上所述,xapian1.2版本的默认数据库类型为Chert。当打开一个已经存在的数据库时,xapian将自动使用Chert后台去处理。

  Chert和Brass都使用写时复制的B+树的数据结构。

2.1.3 Stub database files

  xapian中,stub数据库是一个简单的文本文档,该文档中列出了一系列数据库(本地文件系统或者远程数据库)的地址。

2.1.4 In-memory databases(内存中的数据库)

  xapian中有内存数据库类型,该数据库可以用于测试或者一些短期的用途。然而它效率底下,而且并不支持Xapian的所有特性(如拼写纠错,同义词等)。因此对于生产系统来说,xapian最好使用在磁盘上的数据库如Chert,该数据库在RAM disk上保存文件(RAM:Random-AccessMemory"随机存取存储器",特点是掉电失忆)。

2.1.5 Remote databases and replication(远程数据库和复制)

  xapian的远程数据库后台允许数据库放置在不同的机器上,并通过自定义的协议进入。

  对于不同的机器来说,远程数据库同样支持写时复制的操作。

2.1.6 Concurrent access (并发存取)

  大多数后台数据库允许在写入一个新的数据库的同时查找已经存在的数据库。目前,所有的后台数据库在同一时间仅能存在一个写操作;在同一个数据库上打开另一个写操作将抛出xapian.DatabaseLockError的错误。

  当一个数据库以读的方式打开时,该数据库的固定快照就被确定了。在读该数据库期间,数据库的所有更新对该reader都是不可见的,除非该reader调用xapian.Database.reopen()。如果reader已经读取了数据库的最新版本,那么reopen()将没有任何影响而且对程序没有多少影响。所以当在多线程搜索的时候再次使用相同的xapian.Database对象时,在每次搜索之前调用reopen()是个很合理的策略。

  目前,xapian基于磁盘的后端最多只能同时存在两个版本。因此对于数据库,如果写操作仅做了一次修改,那么reader还是可以使用它的快照访问数据库;但是当写操作做了两次修改后,当reader尝试进入数据库已经修改的一部分时,将受到xapian.DatabaseModifiedError的提醒。在这种情形下,该reader可以使用xapian.Database.reopen()获取最新版本的数据库内容。

2.1.7 Locking

  在xapian的基于磁盘的后台系统中,当一个数据库以写的方式打开,那么该数据库将处于lock状态以防止其他的writer打开。当原来的writer关闭或者自动释放后,该lock将自行释放。

  xapian锁机制一个特殊的地方在于xapian将fork一个子进程来控制该lock,而不是在主进程中控制。This is to avoid the lock being accidentally released due to the slightly unhelpful semantics of fcntl locks.

 

2.2 Documents

  xapian中的Document是由搜索返回的item。当创建一个新的搜索系统时,关键的事情就是要确定系统中的document是什么。在很多情形下可以有不同的选择。例如:搜索一个网站时,对于站点的每一页建立一个document看起来很自然。然而,我们可以选择对于每一页的每一段都建立一个document 或者 将所有的页按主题集中起来,再给每页建立一个document。

  在database中,document以一个唯一的32位正整数id进行标识即document ID。

  Document有三个组成元素:Data, Terms和Values。

2.2.1 Document Data

  document data是document中数据的二进制容器。xapian使得其中的数据完全不可见,而且除了将数据保存在database中,或者当需要时返回以外不再进行其他操作(必要时将压缩)。

  它可以用来作为其他数据的参考(比如外来数据库表格的主键),或者可以用来保存document的全文。

  一般来说,document data最好存储你将要显示给用户的信息。对于document data中数据的存储格式,xapian没有强制规定:根据你的应用,你可能希望使用换行去分割数据,使用JSON或者xml格式,或者使用其他的方式去封装数据。

 

2.3 Terms (Document中的Terms)

  Terms是Xapian中大多数搜索的基础。简单来说,搜索就是将列表中的terms和document中的terms比较,并返回最配对的一列documents。

  一个term通常产生于一篇文档中的每个单词。有很多生成terms的策略。

  通常在一篇文档中,同样的单词将出现很多遍。xapian称每个单词出现的次数为within document frequency"文档内频率"并保存在database中。这通常在搜索引擎根据term出现的权重来给出document时会用到。

  你可能也需要存储每个term的位置。这些位置通常按照word的数量来存储。

  database还保存了terms出现在数据库中的频率的一系列统计数据。term frequency是指某特定的term出现在多少篇document中的个数;collection frequency是指term出现的总次数。

2.3.1 Stemmers

  一个常见的标准化形式是stemming。这个程序将各种不同形式的单词转化为单数形式,例如:将birds和bird指向相同的单词-bird。

  需要注意的是stemmer的输出不一定必须为一个有效的单词;重要的是相近意思的单词都需要转换为同一种形式,方便去搜索到它们。

  stemmer的规则主要根据语言的不同。对于一些语言来说,stemmer是一个可选择的操作。

2.3.2 Fields and term prefixes(未完成)

  将document看作由很多fields组成,每个field由terms组成的文档。实际上,一篇结构化的文档中,field可能是标题也可能是其他的元素(比如水果的颜色)。使用标题会方便进行自由文本搜索;使用其他元素可以用来进行文本的过滤工作。

  

2.4 Term Generator

  xapian提供了xapian.TermGenerator类,方便用户将文本处理成terms。这个类可以分析文本,产生合适的terms,并将他们加入document中。

  当产生terms的时候,xapian.TermGenerator被设置成perform stemming(和停用词)。它可以用来存储文本中单词的位置信息,还可以为拼写纠错程序保存额外的信息。

  如果你希望使用xapian.TermGenerator来处理文档,那么可能在搜索的时候需要用到QueryParser。

 

2.5 Using identifiers with Xapian

  每篇存储在xapian数据库中的文档都有一个唯一的正整数id。

  通常这些id都是唯一的,这样就可以方便用户使用这些id重新为存储的文档建立索引 或者 从xapian的索引中删除失效的文档。有以下两种方法可以使用这些id:

  第一种方法,当索引id数载40亿以内 而且 你的identifier为32位的正整数时,可以为你的identifiers和xapian的docids建立一对一的映射;

  第二种方法是使用一个特别的term用来保存你的identifier,这对于任何类型的identifier均适用。该terms在Chert中的限制长度为245位,所以如果identifier相当长的话,可能需要做其他更复杂的操作。

 

2.6 Index limitations

  当在index中存储数据的时候有以下限制:

  Term Length -

  term的长度在Chert的后台被限制在了245位,但是term中的0个byte会被编码成2个byte。当你需要将url类的事物存储为ID term的时候需要注意到这个长度的限制。

  Document data length -

  document data的限制长度和块大小以及其他因素有关。对于默认块大小为8kb的情形,document data的限制长度为100MB以上。

  Document value length -

  document value的限制长度和data的限制长度相似。但是基于性能的考虑,document value不宜大于几十字节,因为当匹配的时候读取多个100M以上的values的时候,速度会相当慢。

  Document ID

  document id目前是32位,所以在数据库中存储的文档数量最多为2^32-1篇。当为新文档自动分配id时,被删除的文档id将不会再使用,所以这个限制包括了你删除的文档。你可以通过compacting数据库达到再次使用这些被删除的文档的id的目的。

  

  

 

  

  

 

  

  

posted on 2016-08-19 20:03  tanfy  阅读(933)  评论(0编辑  收藏  举报

导航