不久前Hibernate推出了Hibernate Search 3.0 GA,由它的名字大家也可以大概猜到它的作用是对数据库中的数据进行检索的。它是hibernate对著名的全文检索系统Lucene的一个集成方案,作用在于对数据表中某些内容庞大的字段(如声明为text的字段)建立全文索引,这样通过hibernate search就可以对这些字段进行全文检索后获得相应的POJO,从而加快了对内容庞大字段进行模糊搜索的速度(sql语句中like匹配)。

Hibernate Search运行的环境如下:

1、JDK或JRE 5.0以上

2、Hibernate-Search以及相应的依赖包

3、Hibernate Core 3.2.X

4、Hibernate Annotations 3.3.X

一、配置

使用过Lucene的人都知道,Lucene是使用Directory这个概念来存储索引文件的,所以在Hibernate Search中提供了一个初始化、配置化的工厂类DirectoryProvider来生成相应的Directory。而在这里,我使用了FSDirectoryProvider这个工厂类,其中FS代表文件系统,意思是索引文件保存在文件系统中。因此,我们在hibernate.cfg.xml文件中加入了一下内容:

xml 代码
  1. <property name="hibernate.search.default.directory_provider">  
  2.           org.hibernate.search.store.FSDirectoryProvider   
  3. </property>  
  4. <property name="hibernate.search.default.indexBase">  
  5.           E:/temp/index   
  6. </property>  

其中属性hibernate.search.default.indexBase代表索引文件默认的保存位置。

这些属性设置完成后,接下来就是使用Annotation对指定POJO的指定属性进行配置了。如下:

java 代码
  1. @Indexed(index = "text")   
  2. public class Text implements java.io.Serializable   
  3. {   
  4.     @DocumentId  
  5.     private Integer id;   
  6.   
  7.     private String fileName;   
  8.   
  9.     private String filePath;   
  10.   
  11.     @Field(name = "content", store = Store.NO, index = Index.TOKENIZED, analyzer = @Analyzer(impl = ChineseAnalyzer.class))   
  12.     private String content;   
  13.   
  14.     ......   
  15. }  

其中@Indexed用于标示需要建立全文索引的实体类,它包含一个属性index用于标示这个全文索引的名字

@DocumentId用于标示实体类中的唯一的属性保存在索引文件中,是当进行全文检索时可以这个唯一的属性来区分索引中其他实体对象,一般使用实体类中的主键属性

@Field就是用来标示Lucene的Field字段,其中name属性用于标示Field的名称,store属性用于标示这个属性的内容是否需要保存在索引中,index属性标示该字段属性是否进行分词(Index.TOKENIZED),analyzer用于标示建立索引时所使用的分析器是什么类,这里使用Lucene自带的ChineseAnalyzer

评论
billgmh 2008-05-10   回复
test_root 写道
如果我的数据库英字符集的,中文内容保存后都是乱码,
我该如何实例化org.apache.lucene.queryParser.QueryParser,及如何调用
parser.parse()方法?
谢谢


        QueryParser parser = new QueryParser("content", new ChineseAnalyzer());
        parser.setPhraseSlop(0);

        Query query = fullTextSession.createFullTextQuery(parser.parse(word),
                Text.class);
test_root 2008-05-04   回复
如果我的数据库英字符集的,中文内容保存后都是乱码,
我该如何实例化org.apache.lucene.queryParser.QueryParser,及如何调用
parser.parse()方法?
谢谢
test_root 2008-05-04   回复
请问用hibernate search后,如何实现分页?
能把相关的分页代码贴出来吗?
andy54321 2008-02-21   回复
太缺乏项目经验了,

这么多达人,看这些东西好像还有些懵懂的意思

一直想做点什么,真是的。。。。。。
neptune 2008-02-18   回复
还是compass好一些
billgmh 2008-02-12   回复
魔力猫咪 写道
请问在JPA的情况下可以使用吗?Search的注释和JPA注释放在一起会有问题吗?看到例子里用的是专用注释,没有使用JPA的标准注释。


是可以使用的,HS的Annotation是用于配置那些列需要建立索引是不影响JPA的Annotation的。
魔力猫咪 2008-01-22   回复
请问在JPA的情况下可以使用吗?Search的注释和JPA注释放在一起会有问题吗?看到例子里用的是专用注释,没有使用JPA的标准注释。
ivan 2008-01-22   回复
要使用Hibernate Search的功能就不能单纯使用平常的Session来开始事务,进行数据库操作,而是应该改用FullTextSession
 这是错的,只是在搜索的时侯才需要FullTextSession,其他时侯原来咋样还是咋样。
heweiya 2007-12-27   回复
简单就是compass的盗版一样,不知道他是如何支持分词的.
jsjzmxx 2007-12-21   回复
用replace转换一下不就可以了啊
billgmh 2007-10-25   回复
hua0424 写道
8楼的意思是说,对“有一只小鸟(进行)捕食”进行搜索,用关键字"小鸟(进行)"可以查到结果,但是全角括号"小鸟(进行)"就查不到结果,因为后者的"进行"两边是全角的括号


个人感觉,那是由于Luecene自带的中文分词部件功能并不完善,不能对中文很好的支持而已导致,不知我的理解有没有错
hua0424 2007-10-25   回复
8楼的意思是说,对“有一只小鸟(进行)捕食”进行搜索,用关键字"小鸟(进行)"可以查到结果,但是全角括号"小鸟(进行)"就查不到结果,因为后者的"进行"两边是全角的括号
billgmh 2007-10-24   回复
imcaptor 写道
我下载测试了一把,使用象"小鸟(进行)"可以查到结果,但是全角括号"小鸟(进行)"就查不到结果,如何让中文括号也能找到结果?
谢谢!


楼上的意思我不是很清楚,可以详细举个例子吗?
imcaptor 2007-10-23   回复
我下载测试了一把,使用象"小鸟(进行)"可以查到结果,但是全角括号"小鸟(进行)"就查不到结果,如何让中文括号也能找到结果?
谢谢!
wl95421 2007-10-21   回复
lucene有HighLighter的扩展包
billgmh 2007-10-20   回复
暂时只实现了数据检索,不知能否加上关键字的定位,从而做到高亮显示,这个是下一步尝试的目标……
wenson 2007-10-19   回复
不知道性能如何?試試看~
imcaptor 2007-10-19   回复
定,下载运行一下,Annotations 以前还没有用过,还是大学生有学习热情啊。
billgmh 2007-10-03   回复

三、检索

接下来就是说一下如何使用全文检索功能来检索实体对象了。

java 代码
  1. Session session = HibernateUtil.getSession();   
  2. FullTextSession fullTextSession = Search.createFullTextSession(session);   
  3.   
  4. Transaction tx = fullTextSession.beginTransaction();   
  5.   
  6. QueryParser parser = new QueryParser("content"new ChineseAnalyzer());   
  7.   
  8. Query query = fullTextSession.createFullTextQuery(parser.parse(word),   
  9.         Text.class);   
  10.   
  11. List result = query.list();   
  12. for (int i = 0; result != null && i < result.size(); i++)   
  13. {   
  14.     Text pojo = (Text) result.get(i);   
  15.     System.out.println("文件名:" + pojo.getFileName());   
  16.     System.out.println("文件路径:" + pojo.getFilePath());   
  17.     System.out.println();   
  18. }   
  19.   
  20. tx.commit();   
  21. fullTextSession.close();  

首先是建立相应的QueryParser由他来对输入的关键字进行切分后产生Lucene下的Query实例,最后通过FullTextSession的createFullTextQuery方法生成hibernate下的Query实例,执行list方法即可获得查询的实例结果集合。

四、完

以上便是今天我对Hibernate Search的一个尝试,属于很基础很基础的入门,希望可以对大家能有一些启发跟帮助,随文附带我的源代码

billgmh 2007-10-03   回复

二、建立索引

配置完成以上设置之后,Hibernate Search的配置工作算是大功告成了,剩下的就是如何在编码时使用到Hibernate Search。其实Hibernate Search的使用与我们平时Hibernate的使用基本一致,索引的建立工作是可以由Hibernate Search后台自动处理的,无需手工操作,其中的主要差别有

1、Configuration

由于本文中Hibernate Search配置是由Annotation来完成的,所以我们在初始化Configuration、SessionFactory、Session时应该这样写:

java 代码
  1. factory = new AnnotationConfiguration().configure(file).buildSessionFactory();  

使用AnnotationConfiguaration来代理平常使用的Configuration

2、Session

要使用Hibernate Search的功能就不能单纯使用平常的Session来开始事务,进行数据库操作,而是应该改用FullTextSession

java 代码
  1. //获取Session   
  2. Session session = HibernateUtil.getSession();   
  3. //封装Session为FullTextSession   
  4. FullTextSession fullTextSession = Search.createFullTextSession(session);   
  5.   
  6. //开始事务   
  7. Transaction tx = fullTextSession.beginTransaction();   
  8.   
  9. ......   
  10.   
  11. //提交事务   
  12. tx.commit();   
  13. //关闭会话   
  14. fullTextSession.close();  

这样,我们使用FullTextSession进行save,update,delete操作hibernate search将会自动根据配置在后台对相应的域建立全文索引了

发表评论

该博客是同时发布到论坛的,无法评论在论坛已被锁定的帖子

billgmh
  • 浏览: 31277 次
  • 性别: Icon_minigender_1
  • 来自: 广东广州
  • 详细资料
搜索本博客
我的相册
6024ce3a-b42c-451f-bf30-eba1a43b95b9-thumb
Inter
共 3 张
存档
最新评论