Hibernate search实践

本文介绍了如何在Spring+Hibernate项目中利用Hibernate Search整合Lucene,实现全文检索功能。通过添加必要的配置和注解,可以轻松创建和更新索引,支持复杂的搜索查询,如Wild Card、多关键字和模糊查询。
摘要由CSDN通过智能技术生成
也许你的项目正在使用Spring+Hibernate,而你正好需要建立全文检索。Hibernate search可以无缝得整合Hibernate和Lucene,帮助你快速实现功能强大的全文检索。

Hibernate Search通过整合Hibernate core和Lucene建立持久化对象的索引。功能强大而配置简单。下载请到[url=http://hibernate.org/subprojects/search]官方网站[/url]。

Hibernate Search运行的环境如下:

1、JDK或JRE 5.0以上
2、Hibernate-Search以及相应的依赖包
3、Hibernate Core 3.2.X
4、Hibernate Annotations 3.3.X

首先将下载到的JAR包添加到你的项目中。

新建一个领域模型


public class Book {
Integer bookId;
String title;
String author;
String publishDate;
String summarize;
public Integer getBookId() {
return bookId;
}
public void setBookId(Integer bookId) {
this.bookId = bookId;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getPublishDate() {
return publishDate;
}
public void setPublishDate(String publishDate) {
this.publishDate = publishDate;
}
public String getSummarize() {
return summarize;
}
public void setSummarize(String summarize) {
this.summarize = summarize;
}

}


接下来在类中加入Hibernate search注解

//索引名称
@Indexed(index = "books")
//分词器
@Analyzer(impl = MMSegAnalyzer.class)
public class Book {
Integer bookId;
String title;
String author;
String publishDate;
String summarize;

//以对象的唯一标志做为索引中文档的唯一标志
@DocumentId
public Integer getBookId() {
return bookId;
}
public void setBookId(Integer bookId) {
this.bookId = bookId;
}
//索引title字段,并设置了权重
@Field(name = "title", index = Index.TOKENIZED, store = Store.YES, boost=@Boost(2f))
@Boost(1.5f)
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getPublishDate() {
return publishDate;
}
public void setPublishDate(String publishDate) {
this.publishDate = publishDate;
}

//索引摘要字段,并设置权重
@Field(name = "summarize", index = Index.TOKENIZED, store = Store.YES, boost=@Boost(1.2f))
public String getSummarize() {
return summarize;
}
public void setSummarize(String summarize) {
this.summarize = summarize;
}

}


本文没有使用注解来完成类和数据的映射,而是使用book.hbm.xml的映射文件,当然你不用对映射文件做任何改动。如果你想使用注解,直接在类里中加入注解即可。

接下来需要修改hibernate.cfg.xml。在sessionFactory节中加入

<property name="hibernate.search.default.directory_provider">
org.hibernate.search.store.FSDirectoryProvider
</property>
<property name="hibernate.search.default.indexBase">
D:\data\indexs
</property>


到这里,配置和修改就已经完成了。当对象被插入,修改或删除的时候,将会出发索引的修改。

如果你想对数据库中已有的数据建立索引可以



public class IndexBuilder {
static Logger log = Logger.getLogger("IndexBuilder");

public static void main(String[] args) {
Session session = null;
try {
//配置文件
ApplicationContext cxt = new FileSystemXmlApplicationContext(
"..\\WEB-INF\\applicationContext.xml");
SessionFactory sessionFactory = (SessionFactory) cxt
.getBean("sessionFactory");
session = sessionFactory.openSession();
FullTextSession fullTextSession = Search
.createFullTextSession(session);
Query query = session.createQuery("from Book")
.setMaxResults(1000);
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
int j = 0;
int sum = 0;
log.info("start Indexing at "+df.format(Calendar.getInstance().getTimeInMillis()));
while (true) {
session.getTransaction().begin();
List<PvmsMaterialProgram> list = query.setFirstResult(j).list();
for (PvmsMaterialProgram program : list) {
fullTextSession.index(program);
}
session.getTransaction().commit();
j += 1000;
if (list.size() < 1000)
break;
sum += list.size();
log.info("finish " + sum + " records");
}
log.info("end at "+df.format(Calendar.getInstance().getTimeInMillis()));
} catch (Exception e) {
e.printStackTrace();
} finally {
if (session != null)
session.close();
}
}
}


这里每一千条会提交一次。如果出现内存溢出,可以把虚拟机的内存调大一些。


索引构建好了,就可以开始使用查询功能了。Hibernate search支持复杂检索 - 支持Wild Card(诸如*, ?等通配符号),多关键字,模糊查询,排序等。可以使用封装好的接口也可以调用底层的lucene接口(参考官方的手册)。


session = sessionFactory.getCurrentSession();
tx = session.beginTransaction();
String keyword = "足球"
FullTextSession fullTextSession = Search.createFullTextSession(session);
//这里同时对title和摘要字段进行检索
String[] fields = { "title", "summarize" };
String[] values = { keyword, keyword};
MultiFieldQueryParser parser = new MultiFieldQueryParser(
org.apache.lucene.util.Version.LUCENE_30, fields,new MMSegAnalyzer());
org.apache.lucene.search.Query luceneQuery = parser.parse(
org.apache.lucene.util.Version.LUCENE_30, values, fields,new MMSegAnalyzer());
//按发布时间排倒序
org.apache.lucene.search.Sort sort = new Sort(new SortField(
"publishDate", SortField.LONG, true));

FullTextQuery hibQuery = fullTextSession.createFullTextQuery(luceneQuery, Book.class);
//
hibQuery.setSort(sort);
//分页设置
hibQuery.setFirstResult(start);
hibQuery.setMaxResults(limit);
tx.commit();
// log.info("query list = "+hibQuery.list());
List books = hibQuery.list();


这里对title和summarize字段检索关键词"足球",并采取分页查询的策略。

重建索引也非常简单


FullTextSession fullTextSession = Search .getFullTextSession(sessionFactory.getCurrentSession());
//异步
fullTextSession.createIndexer().start();
//同步
//fullTextSession.createIndexer().startAndwait();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值