接下来是要建立搜索的服务类
索引的查询主要是根据传过来的参数,关键字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具有一样的一样的功能,另外还多了个很重要的功能,自动选择正文中最匹配关键字的内容中的一部分输出。因为很多时候一篇文章几千字,我们只想显示有关键字的那部分的摘要,这时候这个功能就很方便.
这之后还要写一个建立索引的服务类,让服务器启动的时候或者定时重建索引.
实现了spring的InitializingBean接口,让服务器启动,bean初始化的时候去建立索引
剩下的就是配置文件了
至于action就不列出代码了,很简单了,只需要传搜索方法的那几个参数过去就可以了.
最后看一下搜索结果示例图:
[img]http://missangel.iteye.com/upload/attachment/128737/bd98a5ab-ca5b-3ba5-86bf-d680c8aaad4e.jpg[/img]
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就不列出代码了,很简单了,只需要传搜索方法的那几个参数过去就可以了.
最后看一下搜索结果示例图:
[img]http://missangel.iteye.com/upload/attachment/128737/bd98a5ab-ca5b-3ba5-86bf-d680c8aaad4e.jpg[/img]