首页  »  lucene

compass之索引格式说明

compass是建立在lucene基础之上的全文搜索框架,它提供了多种格式与索引进行映射的引擎:OSEM、XSEM、RSEM,以致不管你是使用JavaBean的形式进行开发、或用XML来存储数据、甚至是最原始的非面象对象方式的开发,你都会发现Compass适合你,为你的应用添加全文搜索功能。

了解Lucene基本概念的同学应该都很清楚,索引的基本单元是Document,而Document又是由Field组成的。用关系数据库的角度思考,Document相当于一条纪录,Field则相当于纪录中的一个字段(与关系数据库不一样的是Field的值可以有多个)。在Compass的叫法是这样的:一个Document在Compass里面叫Resource,Field在Compass里叫Property。下面我们以OSEM(Object/Search Engine Mapppings)为例来观察一下Compass所创建的索引的真实面目。

下面假设读该文章的同学对Compass至少有感性上的认识。如果发觉阅读困难建议先到官方上去下载一份回来瞅一瞅先。

一、认识对象

使用OSEM引擎,相对应的做法是使用对象与索引进行映射产生关系。为了方便,我直接把Compass的Petclinic的模型拿来开刀了。以Owner和Pet两个类为例,先看看cpm文件代码:

xml 代码
 
  1. <class name="Owner" alias="${petclinic.owner}" extends="person">  
  2.   
  3.         <property name="firstName">  
  4.             <meta-data>${petclinic.firstName}</meta-data>  
  5.         </property>  
  6.   
  7.         <property name="lastName">  
  8.             <meta-data>${petclinic.lastName}</meta-data>  
  9.         </property>  
  10.   
  11.         <property name="address">  
  12.             <meta-data>${petclinic.address}</meta-data>  
  13.         </property>  
  14.   
  15.         <property name="city">  
  16.             <meta-data>${petclinic.city}</meta-data>  
  17.         </property>  
  18.   
  19.         <property name="telephone">  
  20.             <meta-data>${petclinic.telephone}</meta-data>  
  21.         </property>  
  22.   
  23.         <reference name="petsInternal" ref-alias="${petclinic.pet}"  />  
  24.   
  25.  </class>  
  26.   
  27.  <class name="Pet" alias="${petclinic.pet}" extends="named-entity">  
  28.   
  29.         <property name="birthDate">  
  30.             <meta-data>${petclinic.birthdate}</meta-data>  
  31.         </property>  
  32.   
  33.         <component name="type" ref-alias="${petclinic.petType}" />  
  34.   
  35.         <reference name="owner" ref-alias="${petclinic.owner}" />  
  36.   
  37.         <reference name="visitsInternal" ref-alias="${petclinic.visit}"  />  
  38.   
  39.  </class>  

这里就不贴Java源码了,从映射文件上很容易想像Java源码是怎样的。其中Owner和Pet是一对多的关系。而Pet和Visit也是一对多的关系,Visit在这里就不重复贴了。

看起来和Hibernate的映射文件很相似吧。Property标签就不用解释了,稍解释一下Reference。Reference指引用,上面配置显示的Owner和Pet互相都配了Reference可能引起疑惑。引用大部分使用在这种情景:

java 代码
 
  1. @Searchable  
  2. public class A {  
  3.   @SearchableId  
  4.   private Long id;  
  5.   @SearchableReference  
  6.   private B b;    
  7.   // ...  
  8. }  
  9.   
  10. @Searchable  
  11. public class B {  
  12.   @SearchableId  
  13.   private Long id;  
  14.   // ...  
  15. }  

A类持有一个B的成员变量,也叫引用。实际上如果把B改成一个Collection,Compass也会把它当作一个引用处理,它通过检测得知是一般类引用还是集合。实际上Owner和Pet关系的源码是这样的:

java 代码
 
  1. @Searchable  
  2. public class  Owner {  
  3.   @SearchableReference  
  4.   private List petsInternal;    
  5.   // ...  
  6. }  
  7.   
  8. @Searchable  
  9. public class Pet {  
  10.   @SearchableReference  
  11.   private Owner owner;  
  12. }  

对于引用的映射,Compass会把引用目标的ID保存起来,在查询的时候通过ID把关联的对象加载进来,类似于关系数据库的外键。

Compass在创建索引的时候并不是把所有的索引放到一起,而是根据所定义的别名(alais)把不同类型的索引文件分开存储。在PetClinic里面,我们可以看到索引被分成了owner,pet,vet,visit四个文件夹。owner文件夹只存放Owner的索引。一个索引文件夹就像关系数据库中的一张表一样。

二、索引内部结构

现在将要深入到具体一个索引库里面去看一下,这些对象在索引的世界里是如何被组起来的。这时需要用到另外一个好朋友Luck。它将带我们深入分析索引的结构。

打开Luck,file/open lucene index 菜单,浏览到Owner文件夹,打开。这时可以看到Owner和Pet下面存储的文档(Document)都有些什么Field:

Owner的Fields
  1. $/owner/id  
  2. $/owner/petsInternal/colSize  
  3. $/owner/petsInternal/id  
  4. address  
  5. alias  
  6. all  
  7. city  
  8. extendedAlias  
  9. firstName  
  10. lastName  
  11. telephone  

 

Pet的Fields
  1. $/pet/id  
  2. $/pet/owner/id  
  3. $/pet/visitsInternal/colSize  
  4. $/pet/visitsInternal/id  
  5. alias  
  6. all  
  7. birthdate  
  8. extendedAlias  
  9. name  
  10. petType  

从中可以找到规律:

一、alias,all,extendsAlias这三个Field是所有Document都有的,它们各有意义,如Alais用来标识该文档的类型。

二、普通属性使用指定的名字为Field命令,并且在默认情况下,对这些Field的原始值进行索引(Index)、分析(Tokenizer)、并存储(Store)。要改变这种行为,可在配置Meta-data时指定。

三、对象的ID对应的Field名字比较特别,格式是$/(alias)/id

四、引用(Reference)的对象非集合时,将其引用对象的ID以关键字(索引、存储但不分析)的形式作为Field人值及以$/(alias)/(referenceName)/id 为名加到文档中。

五、引用的对象是集合时,将在文档中添加两个Field,命名为$/(alias)/(collection)/colSize的Field将保存所引用集合的Size,命名为$/(alias)/(collection)/id的Field将保存引用集合中每个元素的ID,保存格式均为关键字。到这里你可能会问,一个Field如何保存N个元素的ID,别担心,Luence允许你这样做。下面看一个真实的Document就明白了。

第二行显示出ColSize的值为2,说明该Owner拥有两个Pet,而这两个Pet的ID则可以通过下面两行来找到,是3和4。

到目前为止,对Compass的索引存储应该有了一定的了解了。本文只是一个结论和提供探究的方法,有兴趣的同学还是应该自己动手去做一下。

Lucene中文分词

花了几天在网上逛,为了寻找更好的中文分词方法。很遗憾中文分词一直以来都没有一个标准或者权威的方法,不过方法倒时不少。通常的分词方式有那么几种:一、基于字符串匹配的方式;二、基于理解的方式;三、基于统计方式。目前网上大多数实现都使用第一种,第二种目前处于理论和尝试阶段,还有很长的路要走,第三种就有很好的数学模型作为支撑。

经过分词效果的对比,我决定使用MMSeg作为自己的分词工具。下面是对该分词器的描述的一段引用:

MMSeg只是实现了Chih-Hao Tsai的MMSEG算法,这是一个来源于网络的分词算法。我照抄了算法开始的部分:

MMSEG: A Word Identification System for Mandarin Chinese Text Based on Two Variants of the Maximum Matching Algorithm

Published: 1996-04-29
Updated: 1998-03-06
Document updated: 2000-03-12
License: Free for noncommercial use
Copyright 1996-2006 Chih-Hao Tsai (Email: hao520 at yahoo.com )

您可以在Chih-Hao Tsai's Technology Page找到算法的原文。

如果您只想了解一下MMSeg分词算法的基本原理可以看看MMSeg分词算法简述

------------------------------------------------------------------

但由于MMSeg分词程序不是基于Lucene(不过作者Solo.L有意在编写该程序的时候留了后路,我在做Lucene结合的时候轻而易举。),我在与作者取得联系之后,写了一份Lucene的实现。详情可以查看原作者的Blog文

至于MMSeg的分词原理,除了可以看那份Chih-hao Tsai的英文文档和Solo的算法简述,还可以去看下实现的源码。文档只字片言是说不清的。以后有时间的时候我考虑尝试下写些文档。当然前提是偶自己要搞透来,偶最头疼就是数学啊~~~

最后来看看一个分词效果:

before:到此为止这个简单的但是功能强大的分词器就写完了,下面咱们可以尝试写一个功能更强大的分词器。
after :到此为止_这个_简单_的_但是_功能_强大_的_分词_器_就_写完_了_,_下面_咱们_可以_尝试_写_一个_功能_更_强大_的_分词_器_。
before:我们的祖国是花园,花园的花朵真鲜艳。
after :我们_的_祖国_是_花园_,_花园_的_花朵_真_鲜艳_。
另:来自Google的参考资料:数学之美二--谈谈中文分词
 

Meta

关于本博客...

关于黑莓手机、apple、twitter、互联网、web2.0以及生活的碎言碎语。请在twitter上 follow我,欢迎同好者talk to me bbmyth AT gmail.com。博客Hosting在 webfaction。

赞助商链接

我看我听我读

最新评论

标签

python 空间 开发 计划 年假 工作 诗歌 音乐 西片 恐怖 惊变 django mysql rss 文艺片 太阳 彩色 电影 apache 部署 factcgi lighttpd javascript editor MYMeditor sql 日志 java hibernate orm 数据库 英伦 摇滚 原创 中间件 朋友 erlang 并发 函数式编程 旅游 云南 丽江 发呆 学习 编程 技术 lucene 全文搜索 中文分词 乐队 模板 分页 成功 google pagerank 中文 更新 个性化 秋天 互联网 web ext json ajax 事业 职业 读书 开源 香港 澳门 忧郁 冬天 compass dvd 广州 地下 暴力 美学 声音玩具 独立 备份 数据 琐事 博客 生活 体验 卖唱 接口 设计模式 图表 wiki moin 遇窃 air ria 需求 设计 信息 健康 感悟 人生 真诚 life jquery 杭州 灾害 2008 中国 灾难 哀悼日 jmesa grails flex flash 捐赠 scrum 软件过程 快速开发 plone cms nuexo zope 左小诅咒 demo prototpye AMF actionscript 汉诺塔 算法 递归 结婚 感情 opensource 网络 beautifulSoup 管理 大理 香格里拉 休假 鼻炎 许巍 感性 2009 随想 cpug 聚会 出差 北京 api 创业 商城 blackberry 手机 TD 交流 处事 为人 房子 经济 手机仿真 在线服务 嵌入式 海鲜 p2p easymule apple 技巧 thing gtd task gfw vpn 穿墙 代理 软件管理 翻译 mac 英语 caffeine 休眠 搬家 主机 prism firefox mozilla 免费 php codeigniter url blogspot mindmap mindnode htmlparse easyurl 产品 黑莓 rim 试手机 豆瓣 twitter 微博 杂记 时空 亲人 dabr webfaction host 快速查看 safari appale 桌面 snow 升级 leopard finder 权限 glims python主机 合租 ruby主机 快捷键 itunes 时间管理 原型 画图 招聘 hosting 写作 软件 家庭 广州技术沙龙 postgres 云计算 fuckgfw 内容审检 谷歌 chrome linux odbc database freetds R 统计 书签 浏览器 bookmark tinymce 文件管理 分享 忙碌 旅行 马来西亚 图维导图 freemind 工具 pinax develope shell dropbox barcamp

日志分类

友情链接

博客归档

PowerBy