seam与hibernate search实现了完美的整合,如果你调试一下seam自带的一些demo。就会尝到了seam的甜头,你不得不爱上这东西。在seam当中针对数据库进行全文检索是一个非常容易的事情。你只需做四个事情全文检索的功能就实现了。无需关心hibernate search的session问题和繁杂的检索建立。
1 配置索引文件存放的位置等参数
2 在你想在全文检索的实体声明下与index和feild
3 根据lunce针对相应的字段进行权重打分,建立QueryParser
4 启动时调用索引方法
代码如下:
1 在JAR包下persistence.xml增加,设置保存索引文件的路径
<!-- use a file system based index -->
<property name="hibernate.search.default.directory_provider"
value="org.hibernate.search.store.FSDirectoryProvider"/>
<!-- directory where the indexes will be stored -->
<property name="hibernate.search.default.indexBase" value="./baseindexes"/>
<!-- Not needed with HA 3.3 -->
<property name="hibernate.ejb.event.post-insert" value="org.hibernate.search.event.FullTextIndexEventListener"/>
<property name="hibernate.ejb.event.post-update" value="org.hibernate.search.event.FullTextIndexEventListener"/>
<property name="hibernate.ejb.event.post-delete" value="org.hibernate.search.event.FullTextIndexEventListener"/>
2 在你想在全文检索的实体声明下与index和feild
/*******************************************************************************
* 文件名:FullTextContent.java<br>
* 版本: <br>
* 描述: <br>
* 版权所有: <br>
* <br>
* 创建者: 沙振中 <br>
* 创建日期: May 13, 2009 <br>
* 修改者: <br>
* 修改日期: <br>
* 修改说明: <br>
******************************************************************************/
package org.shaneseam.entitybean;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import org.hibernate.search.annotations.DocumentId;
import org.hibernate.search.annotations.Field;
import org.hibernate.search.annotations.Index;
import org.hibernate.search.annotations.Indexed;
import org.hibernate.search.annotations.Store;
import org.jboss.seam.annotations.Name;
@Entity
@Name("fullTextContent")
@Indexed
public class FullTextContent implements Serializable {
private static final long serialVersionUID = 1L;
Long fullTextContentId;
String contentOne;
String contentTwo;
String contentThree;
String contentFour;
String contentFive;
public FullTextContent()
{}
/**
* @return the fullTextContentId
*/
@Id @GeneratedValue
@DocumentId
public Long getFullTextContentId() {
return fullTextContentId;
}
/**
* @param fullTextContentId the fullTextContentId to set
*/
public void setFullTextContentId(Long fullTextContentId) {
this.fullTextContentId = fullTextContentId;
}
/**
* @return the contentOne
*/
@Field(name="contentOne",index=Index.TOKENIZED,store=Store.YES)
public String getContentOne() {
return contentOne;
}
/**
* @param contentOne the contentOne to set
*/
public void setContentOne(String contentOne) {
this.contentOne = contentOne;
}
/**
* @return the contentTwo
*/
@Field(name="contentTwo",index=Index.TOKENIZED,store=Store.YES)
public String getContentTwo() {
return contentTwo;
}
/**
* @param contentTwo the contentTwo to set
*/
public void setContentTwo(String contentTwo) {
this.contentTwo = contentTwo;
}
/**
* @return the contentThree
*/
@Field(name="contentThree",index=Index.TOKENIZED,store=Store.YES)
public String getContentThree() {
return contentThree;
}
/**
* @param contentThree the contentThree to set
*/
public void setContentThree(String contentThree) {
this.contentThree = contentThree;
}
/**
* @return the contentFour
*/
@Field(name="contentFour",index=Index.TOKENIZED,store=Store.YES)
public String getContentFour() {
return contentFour;
}
/**
* @param contentFour the contentFour to set
*/
public void setContentFour(String contentFour) {
this.contentFour = contentFour;
}
/**
* @return the contentFive
*/
@Field(name="contentFive",index=Index.TOKENIZED,store=Store.YES)
public String getContentFive() {
return contentFive;
}
/**
* @param contentFive the contentFive to set
*/
public void setContentFive(String contentFive) {
this.contentFive = contentFive;
}
}
3 根据lunce针对相应的字段进行权重打分,建立QueryParser
/*******************************************************************************
* 文件名:FullTextAction.java<br>
* 版本: <br>
* 描述: <br>
* 版权所有: <br>
* <br>
* 创建者: 沙振中 <br>
* 创建日期: May 13, 2009 <br>
* 修改者: <br>
* 修改日期: <br>
* 修改说明: <br>
******************************************************************************/
package org.shaneseam.action;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.ejb.Remove;
import javax.ejb.Stateful;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.queryParser.MultiFieldQueryParser;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.shaneseam.action.inte.FullText;
import org.shaneseam.entitybean.FullTextContent;
import org.hibernate.search.jpa.FullTextEntityManager;
import org.hibernate.search.jpa.FullTextQuery;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Out;
import org.jboss.seam.annotations.datamodel.DataModel;
@Stateful
@Name("fullTextAction")
public class FullTextAction implements FullText,Serializable {
@PersistenceContext
EntityManager em;
@DataModel
List<FullTextContent> searchResults;
@In(required=false)
@Out(required=false)
String searchQuery;
public String goPage() {
return "goPage";
}
public String search() {
System.out.println("search begin");
FullTextQuery query;
List<FullTextContent> items = null;
try {
query = searchQuerys(searchQuery);
items = query.setMaxResults(100).getResultList();
} catch (ParseException e) {
e.printStackTrace();
}
for(FullTextContent item : items)
{
System.out.println(item.getContentOne());
}
searchResults=items;
System.out.println("搜索出的数据的数量是:"+searchResults.size()+items.size());
return null;
}
private FullTextQuery searchQuerys(String searchQuery) throws ParseException
{
System.out.println("searchQuery begin"+searchQuery);
Map<String,Float> boostPerField = new HashMap<String,Float>();
boostPerField.put("contentOne", 4f);
boostPerField.put("contentTwo", 2f);
boostPerField.put("contentThree", 2f);
boostPerField.put("contentFour", 0.5f);
String[] contextFields = {"contentOne", "contentTwo", "contentThree", "contentFour"};
QueryParser parser = new MultiFieldQueryParser(contextFields, new StandardAnalyzer(), boostPerField);
parser.setAllowLeadingWildcard(true);
org.apache.lucene.search.Query luceneQuery;
luceneQuery = parser.parse(searchQuery);
System.out.println("searchQuery end");
return ( (FullTextEntityManager) em ).createFullTextQuery(luceneQuery, FullTextContent.class);
}
@Remove
public void destroy() {
}
}
4 启动时调用索引方法
//$Id: IndexerAction.java 6551 2007-10-16 19:19:22Z nrichards $
package org.shaneseam.action;
import java.util.Date;
import javax.ejb.Remove;
import javax.ejb.Stateful;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.shaneseam.action.inte.Indexer;
import org.shaneseam.entitybean.FullTextContent;
import org.hibernate.search.FullTextSession;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Create;
import org.jboss.seam.annotations.Destroy;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.Startup;
/**
* Re index the needed entities
*
* @author Emmanuel Bernard
*/
@Name("indexer")
@Stateful
@Scope(ScopeType.APPLICATION)
@Startup
public class IndexerAction implements Indexer
{
private Date lastIndexingTime;
@PersistenceContext
private EntityManager em;
public Date getLastIndexingTime()
{
return lastIndexingTime;
}
@Create
public void index()
{
indexAllClasses(FullTextContent.class);
lastIndexingTime = new Date();
}
private FullTextSession getFullTextSession()
{
return (FullTextSession) em.getDelegate();
}
@SuppressWarnings("unchecked")
private void indexAllClasses(Class... entityTypes)
{
FullTextSession fullTextSession = getFullTextSession();
for (Class entityType : entityTypes)
{
for (Object obj : fullTextSession.createCriteria(entityType).list())
{
fullTextSession.index(obj);
}
}
}
@Remove
@Destroy
public void stop() {}
}