接下来是要建立搜索的服务类
- 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