利用python和xapian构建高速检索引擎
首先弄大白几个观念:Documents 、terms and posting在信息检索(IR)中,我们诡计要获取的项称之“document”,每一个document是被一个terms荟萃所描写的。 “document”和“term”这两个词汇是IR中的术语,它们是来自“图书馆打点学”的。凡是一个document认为是一块文本,(Usually a document is thought of as a piece of text, most likely in a machine readable form), 而一个term则是一个词语或短语以用作描写document的,在document中大大都市存在着多个term,譬喻某个document是跟_口腔_ _卫生_相关的,那么大概会存在着以下的terms:“tooth”、“teeth”、“toothbrush”、“decay”、“cavity”、“plaque”或“diet”等等。
假如在一个IR系统中,存在一个名为D的document,此document被一个名为t的term所描写,那么t被认为索引了D,可以用以下式子表 示:t->D。在实际应用的一个IR系统中凡是是多个documents,如D1, D2, D3 …构成的荟萃,且有多个term,如t1, t2, t3 …构成的荟萃,从而有以下干系:ti -> Dj。
假如某个特定的term索引了某个特定的document,那么称之为posting,说白了posting就是带position信息的term,在相关度检索中大概有必然的用途的。
给定一个名为D的document,存在着一个terms列表索引着它,我们称之为D的term list。
给定一个名为t的term,它索引着一个documents列表,这称之为t的posting list(利用“Document list”大概会在叫法上更一致,但听起来过于空泛)。
在一个存在于计较机的IR系统中,terms是存储于索引文件中的。term可以用作有效地查找它的posting list,在posting list里,每一个document带有一个很短的标识符,就是document id。简朴来说,一个posting list可以被认为是一个由document ids构成的荟萃,而term list则是一个字符串构成的荟萃。在某些IR系统的内部是利用数字来暗示term的,因此在这些系统中,term list则是数字构成的荟萃,而Xapian则不是这样,它利用原汁原味的term,而利用前缀来压缩存储空间。
Terms不必然是要是document中呈现的词语,凡是它们会被转换为小写,并且往往它们被词干提取算法处理惩罚过,因此通过一个值为“connect” 的term大概会检索出一系列的词语,例“connect”、“connects”、“connection”或“connected”等,而一个词语 也大概发生多个的terms,譬喻你会将提取出的词干和未提取的词语都索引起来。虽然,这大概只合用于英语、法语或拉丁语等西欧系列的语言,而中文的分词 则有很大的区别,总的来说,西欧语系的语言分词与中文分词有以下的区别:
l. 拿英语来说,凡是环境下英语的每一个词语之间是用空格来离隔的,而中文则否则,甚至可以极度到整篇文章都不呈现空格或标点标记。 2. 像上面提到的,“connect”、“connects”、“connection”或“connected”别离的意思“动词性质的毗连”、“动词性质 的第三人称的毗连”、“名称性质的毗连”或“毗连的已往式”,但在中文里,用“毗连”就可以暗示全部了,险些不需要词干提取。这意味着英语的各类词性大部 分是有章可循的,而中文的词性则是天马行空的。 3. 第二点只是中文分词很是坚苦的一个缩影,要完全正确地标识出某个句子的语意是很坚苦的,譬喻“中华人民共和国创立了”这个句子,可以分出“中华”、“华 人”、“人民”、“共和国”、“创立”等词语,不外个中“华人”跟这个句子其实干系不大。咋一眼看上去很简朴,但呆板那有这么容易懂这个中的玄妙呢?
Values
Values是附加在document上一种元数据,每一个document可以有多个values,这些values通过差异的数字来标识。 Values被设计成在匹配进程中快速地会见,它们可以用作排序、列队多余反复的document和范畴检索等用途。固然values并没有长度限制,但 最好让它们尽大概短,假如你仅仅是想存储某个字段以便作为功效显示,那么发起您最好将它们生存在document的data中。
Document data
每一个Document只有一个data,可以是任意范例名目标数据,虽然在存储的时候请先转换为字符串。这听上去大概有点离奇,实情是这样的:假如要存 储的数据是文本名目,则可以直接存储;假如要存储的数据是各类的工具,请先序列化成二进制流再生存,而在读取的时候反序列化读取。
posting
posting是带position的term.
# -*- coding: gb18030 -*- import xapian testdatas = [u'abc test python1',u'abcd testing python2'] def buildtest(): database = xapian.WritableDatabase('indexes/', xapian.DB_CREATE_OR_OPEN) stemmer = xapian.Stem("english") for data in testdatas: doc = xapian.Document() doc.set_data(data) for term in data.split(): doc.add_term(term) database.add_document(doc) if __name__ == '__main__': buildtest()
执行后,当前目次下生成索引库。
[sh]
[[email protected] indexes]$ ll
总用量 52
-rw-rw-r– 1 ec2-user ec2-user 0 7月 28 16:06 flintlock
-rw-rw-r– 1 ec2-user ec2-user 28 7月 28 16:06 iamchert
-rw-rw-r– 1 ec2-user ec2-user 13 7月 28 16:06 postlist.baseA
-rw-rw-r– 1 ec2-user ec2-user 14 7月 28 16:06 postlist.baseB
-rw-rw-r– 1 ec2-user ec2-user 8192 7月 28 16:06 postlist.DB
-rw-rw-r– 1 ec2-user ec2-user 13 7月 28 16:06 record.baseA
-rw-rw-r– 1 ec2-user ec2-user 14 7月 28 16:06 record.baseB
-rw-rw-r– 1 ec2-user ec2-user 8192 7月 28 16:06 record.DB
-rw-rw-r– 1 ec2-user ec2-user 13 7月 28 16:06 termlist.baseA
-rw-rw-r– 1 ec2-user ec2-user 14 7月 28 16:06 termlist.baseB
-rw-rw-r– 1 ec2-user ec2-user 8192 7月 28 16:06 termlist.DB
我们下篇再先容如何去查询索引。