Hibernate search(全文检索)

搜索引擎

全文搜索引擎

全文搜索引擎是名副其实的搜索引擎,国外代表有Google,国内则有著名的百度搜索。它们从互联网提取各个网站的信息(以网页文字为主),建立起数据库,并能检索与用户查询条件相匹配的记录,按一定的排列顺序返回结果。

  根据搜索结果来源的不同,全文搜索引擎可分为两类,一类拥有自己的网页抓取、索引、检索系统(Indexer),有独立的“蜘蛛”(Spider)程序、或爬虫(Crawler)、或“机器人”(Robot)程序(这三种称法意义相同),能自建网页数据库,搜索结果直接从自身的数据库中调用,上面提到的Google和百度就属于此类;另一类则是租用其他搜索引擎的数据库,并按自定的格式排列搜索结果,如Lycos搜索引擎。
目录索引

  目录索引虽然有搜索功能,但严格意义上不能称为真正的搜索引擎,只是按目录分类的网站链接列表而已。用户完全可以按照分类目录找到所需要的信息,不依靠关键词(Keywords)进行查询。目录索引中最具代表性的莫过于大名鼎鼎的Yahoo、新浪分类目录搜索。

元搜索引擎

元 搜索引擎(META Search Engine)接受用户查询请求后,同时在多个搜索引擎上搜索,并将结果返回给用户。著名的元搜索引擎有InfoSpace、Dogpile、 Vivisimo等,中文元搜索引擎中具代表性的是搜星搜索引擎。在搜索结果排列方面,有的直接按来源排列搜索结果,如Dogpile;有的则按自定的规则将结果重新排列组合,如Vivisimo。
全文搜索引擎的基本原理

具体再详细的概念参照baidu吧 搜索引擎

lucenne

java领域的全文搜索的工具包lucene不仅可以对文本数据进行搜索,还可以对html,excel和pdf等格式的文件建立索引并且进行搜索。

Hibernate search底层使用的就是 lucene。

http://lucene.apache.org

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

上述都属于概念

Hibernate Search特点

支持索引数据的自动更新

支持众多的搜索方式,使用关键词进行搜索,也可以使用通配符进行搜索,还可以使用近似或者同义词进行搜索

支持搜索集群

支持对Lucene API直接的调用

Hibernate Search的类库
hibernate-search.jar
lucene-core.jar
hibernate-commons-annotations.jar

需要修改Hibernate.cfg.xml配置使用Hibernate Search

Xml代码
  1. <propertyname="hibernate.search.default.directory_provider">
  2. org.hibernate.search.store.FSDirectoryProvider 
  3. </property>
  4. <propertyname="hibernate.search.default.indexBase">
  5. D:/temp/index 
  6. </property>
  7. <mappingresource="com/rbh/examples/Guestbook.hbm.xml"/>
  8. <eventtype="post-update">
  9. <listenerclass="org.hibernate.search.event.FullTextIndexEventListener"/>
  10. </event>
  11. <eventtype="post-insert">
  12. <listenerclass="org.hibernate.search.event.FullTextIndexEventListener"/>
  13. </event>
  14. <eventtype="post-delete">
  15. <listenerclass="org.hibernate.search.event.FullTextIndexEventListener"/>
  16. </event>
  17. <eventtype="post-collection-recreate">
  18. <listenerclass="org.hibernate.search.event.FullTextIndexEventListener"/>
  19. </event>
  20. <eventtype="post-collection-remove">
  21. <listenerclass="org.hibernate.search.event.FullTextIndexEventListener"/>
  22. </event>
  23. <eventtype="post-collection-update">
  24. <listenerclass="org.hibernate.search.event.FullTextIndexEventListener"/>
  25. </event>

修改持久化类,使用注解配置全文索引

Java代码
  1. @Indexed
  2. publicclassGuestbookimplementsjava.io.Serializable
  3. ............. 
  4. @DocumentId//表示这个对象的主
  5. publicIntegergetId()
  6. returnthis.id; 
  7. @Field(store=Store.YES) 
  8. publicStringgetName()
  9. returnthis.name; 
  10. ............... 
  11. }

对持久化对象建立索引

Java代码
  1. Session session = HibernateSessionFactoryUtil.getSessionFactory().getCurrentSession(); 
  2. session.getTransaction().begin(); 
  3. FullTextSession ftSession = org.hibernate.search.Search.getFullTextSession(session); 
  4. List<Guestbook> guestbooks = session.createQuery("fromGuestbook").list(); 
  5. for (Guestbook gb : guestbooks)
  6. ftSession.index(gb); 
  7. ftSession.getTransaction().commit();

搜索全文索引后的持久化对象

Java代码
  1. QueryParser parser = newQueryParser("title",newStandardAnalyzer()); 
  2. org.apache.lucene.search.Query luceneQuery = null
  3. try
  4. luceneQuery = parser.parse("title:test");//buildLucenequery
  5. } catch(ParseExceptione)
  6. e.printStackTrace(); 
  7. Session session = HibernateSessionFactoryUtil.getSessionFactory().getCurrentSession(); 
  8. session.getTransaction().begin(); 
  9. FullTextSession ftSession = org.hibernate.search.Search.getFullTextSession(session); 
  10. org.hibernate.Query query = ftSession.createFullTextQuery(luceneQuery,Guestbook.class); 
  11. query.setMaxResults(20); 
  12. query.setFirstResult(0); 
  13. List<Guestbook> guestbooks = query.list(); 
  14. for (Guestbook gb : guestbooks)
  15. printGuestbook(gb); 
  16. ftSession.getTransaction().commit();

使用luke工具,查看索引数据

Luke是一款显示Lucene索引数据、修改Lucene索引数据和进行模拟搜索的开源工具

注意:现在版本为luke-src-0.9.9,下载后也为lukeall0.9.9.jar cmd下无法运行lukeall0.9.9.jar 改名为lukeall.jar,运行java -jar lukeall.jar 即可

中文分词

把中文的句子切分成有意义的词,这就是中文分词

中文分词的基本机制

一种使用词库匹配
另一种使用自动切分算法

词库切分与自动切分的比较

Hibernate Search 使用第三方的中文分词组件

IK Analyzer中文分词组件--------下载地址http://code.google.com/p/ik-analyzer/

"庖丁解牛"分词组件-------下载地址http://code.google.com/p/paoding/

配置"庖丁解牛"分词组件

1,把paoding-analysis-2.0.4-beta解压缩,给项目中加入paoding-analysis.jar。

2,把dic文件夹放到项目的根目录中。dic文件夹里是paoding的词库。

3,配置paoding的词库:把paoding-analysis-2.0.4-beta\src里面的paoding-dic-home.properties拷贝到项目的根目录下。编辑如下:

修改paoding .dic .home .config-fisrt=this ,使得程序知道该配置文件
修改paoding .dic .home =classpath:dic ,指定字典的所在路径。绝对路径也可以,但是不好持久化类中注解

Java代码
  1. ...... 
  2. @Indexed
  3. @Analyzer(impl = net.paoding.analysis.analyzer.PaodingAnalyzer.class
  4. publicclassGuestbookimplementsjava.io.Serializable
  5. ....... 
  6. }

 

参考:

一、配置

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

xml 代码
  1. < propertyname = "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 classText implementsjava.io.Serializable  
  3. {  
  4.     @DocumentId  
  5.     privateInteger id;  
  6.  
  7.     privateString fileName;  
  8.  
  9.     privateString filePath;  
  10.  
  11.     @Field (name ="content" , store = Store.NO, index = Index.TOKENIZED, analyzer =@Analyzer (impl = ChineseAnalyzer.class ))  
  12.     privateString content;  
  13.  
  14.     ......  

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

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

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

二、建立索引

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

1、Configuration

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

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

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

2、Session

要使用Hibernate Search的功能就不能单纯使用平常的Session来开始事务,进行数据库操作,而是应该改用FullTextSession(实体类配置好了用平常Session就可生成索引。)

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将会自动根据配置在后台对相应的域建立全文索引了

三、检索

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

java 代码
  1. Session session = HibernateUtil.getSession();  
  2. FullTextSession fullTextSession = Search.createFullTextSession(session);  
  3.  
  4. Transaction tx = fullTextSession.beginTransaction();  
  5.  
  6. QueryParser parser = newQueryParser( "content", newChineseAnalyzer());  
  7.  
  8. Query query = fullTextSession.createFullTextQuery(parser.parse(word),  
  9.         Text. class);  
  10.  
  11. List result = query.list();  
  12. for ( inti = 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方法即可获得查询 的实例结果集合。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值