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() {}
}