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的索引存储应该有了一定的了解了。本文只是一个结论和提供探究的方法,有兴趣的同学还是应该自己动手去做一下。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值