接下來是要建立搜索的服務類
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import org.compass.core.Compass;
- import org.compass.core.CompassCallback;
- import org.compass.core.CompassException;
- import org.compass.core.CompassHighlighter;
- import org.compass.core.CompassHits;
- import org.compass.core.CompassQuery;
- import org.compass.core.CompassSession;
- import org.compass.core.CompassTemplate;
- import org.compass.core.CompassTransaction;
- import cn.rgcenter.entity.Article;
- public class SearchServiceBean {
- private Compass compass;
- /** 索引查詢 * */
- public Map find(final String keywords, final String type, final int start,
- final int end) {
- CompassTemplate ct = new CompassTemplate(compass);
- return ct.execute(new CompassCallback<Map>() {
- public Map doInCompass(CompassSession session)
- throws CompassException {
- List result = new ArrayList();
- int totalSize = 0;
- Map container = new HashMap();
- CompassQuery query = session.queryBuilder().queryString(
- keywords).toQuery();
- CompassHits hits = query.setAliases(type).hits();
- totalSize = hits.length();
- container.put("size", totalSize);
- int max = 0;
- if (end < hits.length()) {
- max = end;
- } else {
- max = hits.length();
- }
- if(type.equals("article")){
- for (int i = start; i < max; i++) {
- Article article = (Article) hits.data(i);
- String title = hits.highlighter(i).fragment("title");
- if (title != null) {
- article.setTitle(title);
- }
- String content = hits.highlighter(i).setTextTokenizer(
- CompassHighlighter.TextTokenizer.AUTO)
- .fragment("content");
- if (content != null) {
- article.setContent(content);
- }
- result.add(article);
- }
- }
- container.put("result", result);
- return container;
- }
- });
- }
- public Compass getCompass() {
- return compass;
- }
- public void setCompass(Compass compass) {
- this.compass = compass;
- }
- }
索引的查詢主要是根據傳過來的參數,關鍵字keywords,是搜索的關鍵字,類型type,先判斷是不是要搜索文章,因爲一般來說,頁面的搜索引擎不單單隻搜索文章一個實體.
至於int 和end是爲了分頁取出部分結果的.
String title = hits.highlighter(i).fragment("title");這段是檢索titile這個屬性有沒有出現搜索的關鍵字,有就將它高亮(其實就是在關鍵字前後加個<font></font>的html標記設置顏色,等下可以看到在配置文件裏可以自由設置高亮的顏色).
String content = hits.highlighter(i).setTextTokenizer(
CompassHighlighter.TextTokenizer.AUTO)
.fragment("content");
這段代碼和上面的title具有一樣的一樣的功能,另外還多了個很重要的功能,自動選擇正文中最匹配關鍵字的內容中的一部分輸出。因爲很多時候一篇文章幾千字,我們只想顯示有關鍵字的那部分的摘要,這時候這個功能就很方便.
這之後還要寫一個建立索引的服務類,讓服務器啓動的時候或者定時重建索引.
- import org.compass.gps.CompassGps;
- import org.springframework.beans.factory.InitializingBean;
- public class CompassIndexBuilder implements InitializingBean {
- // 是否需要建立索引,可被設置爲false使本Builder失效.
- private boolean buildIndex = false;
- // 索引操作線程延時啓動的時間,單位爲秒
- private int lazyTime = 10;
- // Compass封裝
- private CompassGps compassGps;
- // 索引線程
- private Thread indexThread = new Thread() {
- @Override
- public void run() {
- try {
- Thread.sleep(lazyTime * 1000);
- System.out.println("begin compass index...");
- long beginTime = System.currentTimeMillis();
- // 重建索引.
- // 如果compass實體中定義的索引文件已存在,索引過程中會建立臨時索引,
- // 索引完成後再進行覆蓋.
- compassGps.index();
- long costTime = System.currentTimeMillis() - beginTime;
- System.out.println("compss index finished.");
- System.out.println("costed " + costTime + " milliseconds");
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- };
- /**
- * 實現<code>InitializingBean</code>接口,在完成注入後調用啓動索引線程.
- */
- public void afterPropertiesSet() throws Exception {
- if (buildIndex) {
- indexThread.setDaemon(true);
- indexThread.setName("Compass Indexer");
- indexThread.start();
- }
- }
- public void setBuildIndex(boolean buildIndex) {
- this.buildIndex = buildIndex;
- }
- public void setLazyTime(int lazyTime) {
- this.lazyTime = lazyTime;
- }
- public void setCompassGps(CompassGps compassGps) {
- this.compassGps = compassGps;
- }
- }
實現了spring的InitializingBean接口,讓服務器啓動,bean初始化的時候去建立索引
剩下的就是配置文件了
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:aop="http://www.springframework.org/schema/aop"
- xmlns:tx="http://www.springframework.org/schema/tx"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
- http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
- http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
- <bean id="annotationConfiguration"
- class="org.compass.annotations.config.CompassAnnotationsConfiguration">
- </bean>
- <!-- compass Bean -->
- <bean id="compass" class="org.compass.spring.LocalCompassBean">
- <property name="compassConfiguration"
- ref="annotationConfiguration" />
- <!-- 數據索引存儲位置 -->
- <property name="connection">
- <value>/compass/indexes</value>
- </property>
- <property name="transactionManager" ref="transactionManager" />
- <property name="compassSettings">
- <props>
- <prop key="compass.transaction.factory">
- org.compass.spring.transaction.SpringSyncTransactionFactory
- </prop>
- <prop
- key="compass.engine.highlighter.default.formatter.simple.pre">
- <![CDATA[<span style='background-color:yellow;color:red;'>]]>
- </prop>
- <prop
- key="compass.engine.highlighter.default.formatter.simple.post">
- <![CDATA[</span>]]>
- </prop>
- <!--定義分詞器-->
- <prop
- key="compass.engine.analyzer.default.type">
- org.mira.lucene.analysis.IK_CAnalyzer
- </prop>
- </props>
- </property>
- <property name="classMappings">
- <list>
- <value>cn.rgcenter.entity.Article</value>
- </list>
- </property>
- </bean>
- <!--hibernate驅動-->
- <bean id="hibernateGpsDevice"
- class="org.compass.spring.device.hibernate.dep.SpringHibernate3GpsDevice">
- <property name="name">
- <value>hibernateDevice</value>
- </property>
- <property name="sessionFactory" ref="sessionFactory" />
- <property name="mirrorDataChanges">
- <value>true</value>
- </property>
- </bean>
- <!-- 數據庫中的數據變化後同步更新索引 -->
- <bean id="hibernateGps"
- class="org.compass.gps.impl.SingleCompassGps" init-method="start"
- destroy-method="stop">
- <property name="compass">
- <ref bean="compass" />
- </property>
- <property name="gpsDevices">
- <list>
- <bean
- class="org.compass.spring.device.SpringSyncTransactionGpsDeviceWrapper">
- <property name="gpsDevice" ref="hibernateGpsDevice" />
- </bean>
- </list>
- </property>
- </bean>
- <!-- compass模版 -->
- <bean id="compassTemplate"
- class="org.compass.core.CompassTemplate">
- <property name="compass" ref="compass" />
- </bean>
- <!-- 定時重建索引(利用quartz)或隨Spring ApplicationContext啓動而重建索引 -->
- <bean id="compassIndexBuilder"
- class="cn.rgcenter.compass.service.CompassIndexBuilder"
- lazy-init="false">
- <property name="compassGps" ref="hibernateGps" />
- <property name="buildIndex" value="true" />
- <property name="lazyTime" value="5" />
- </bean>
- <!-- 搜索引擎服務類 -->
- <bean id="searchService"
- class="cn.rgcenter.compass.service.SearchServiceBean">
- <property name="compass">
- <ref bean="compass" />
- </property>
- </bean>
- <!-- 搜索引擎Action -->
- <bean id="searchAction" class="cn.rgcenter.action.SearchAction">
- <property name="searchService">
- <ref bean="searchService" />
- </property>
- </bean>
- </beans>
至於action就不列出代碼了,很簡單了,只需要傳搜索方法的那幾個參數過去就可以了.
最後看一下搜索結果示例圖:
本文轉自於:http://jeemiss.iteye.com/blog/432634