分享

用compass实现站内全文搜索引擎(二) - Miss - JavaEye技术网站

 昵称2578135 2010-08-18

用compass实现站内全文搜索引擎(二)

接下来是要建立搜索的服务类

Java代码 复制代码
  1.   
  2. import java.util.ArrayList;   
  3. import java.util.HashMap;   
  4. import java.util.List;   
  5. import java.util.Map;   
  6. import org.compass.core.Compass;   
  7. import org.compass.core.CompassCallback;   
  8. import org.compass.core.CompassException;   
  9. import org.compass.core.CompassHighlighter;   
  10. import org.compass.core.CompassHits;   
  11. import org.compass.core.CompassQuery;   
  12. import org.compass.core.CompassSession;   
  13. import org.compass.core.CompassTemplate;   
  14. import org.compass.core.CompassTransaction;   
  15. import cn.rgcenter.entity.Article;   
  16.   
  17. public class SearchServiceBean {   
  18.   
  19.     private Compass compass;   
  20.     /** 索引查询 * */  
  21.     public Map find(final String keywords, final String type, final int start,   
  22.             final int end) {   
  23.         CompassTemplate ct = new CompassTemplate(compass);   
  24.         return ct.execute(new CompassCallback<Map>() {   
  25.   
  26.             public Map doInCompass(CompassSession session)   
  27.                     throws CompassException {   
  28.                 List result = new ArrayList();   
  29.                 int totalSize = 0;   
  30.                 Map container = new HashMap();   
  31.                 CompassQuery query = session.queryBuilder().queryString(   
  32.                         keywords).toQuery();   
  33.                 CompassHits hits = query.setAliases(type).hits();   
  34.                 totalSize = hits.length();   
  35.                 container.put("size", totalSize);   
  36.                 int max = 0;   
  37.                 if (end < hits.length()) {   
  38.                     max = end;   
  39.                 } else {   
  40.                     max = hits.length();   
  41.                 }   
  42.   
  43.        if(type.equals("article")){   
  44.                     for (int i = start; i < max; i++) {   
  45.                         Article article = (Article) hits.data(i);   
  46.                         String title = hits.highlighter(i).fragment("title");   
  47.                         if (title != null) {   
  48.                             article.setTitle(title);   
  49.                         }   
  50.                         String content = hits.highlighter(i).setTextTokenizer(   
  51.                                 CompassHighlighter.TextTokenizer.AUTO)   
  52.                                 .fragment("content");   
  53.                         if (content != null) {   
  54.   
  55.                             article.setContent(content);   
  56.                         }   
  57.                         result.add(article);   
  58.                     }   
  59.                 }   
  60.                 container.put("result", result);   
  61.                 return container;   
  62.             }   
  63.         });   
  64.     }   
  65.   
  66.     public Compass getCompass() {   
  67.         return compass;   
  68.     }   
  69.   
  70.     public void setCompass(Compass compass) {   
  71.         this.compass = compass;   
  72.     }   
  73.   
  74. }  



索引的查询主要是根据传过来的参数,关键字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具有一样的一样的功能,另外还多了个很重要的功能,自动选择正文中最匹配关键字的内容中的一部分输出。因为很多时候一篇文章几千字,我们只想显示有关键字的那部分的摘要,这时候这个功能就很方便.


这之后还要写一个建立索引的服务类,让服务器启动的时候或者定时重建索引.

Java代码 复制代码
  1. import org.compass.gps.CompassGps;   
  2. import org.springframework.beans.factory.InitializingBean;   
  3.   
  4. public class CompassIndexBuilder implements InitializingBean {     
  5.        
  6.     // 是否需要建立索引,可被设置为false使本Builder失效.      
  7.     private boolean buildIndex = false;      
  8.      
  9.     // 索引操作线程延时启动的时间,单位为秒      
  10.     private int lazyTime = 10;      
  11.      
  12.     // Compass封装      
  13.     private CompassGps compassGps;      
  14.      
  15.     // 索引线程      
  16.     private Thread indexThread = new Thread() {      
  17.      
  18.         @Override     
  19.         public void run() {      
  20.             try {      
  21.                 Thread.sleep(lazyTime * 1000);      
  22.                 System.out.println("begin compass index...");      
  23.                 long beginTime = System.currentTimeMillis();      
  24.                 // 重建索引.      
  25.                 // 如果compass实体中定义的索引文件已存在,索引过程中会建立临时索引,      
  26.                 // 索引完成后再进行覆盖.      
  27.                 compassGps.index();      
  28.                 long costTime = System.currentTimeMillis() - beginTime;      
  29.                 System.out.println("compss index finished.");      
  30.                 System.out.println("costed " + costTime + " milliseconds");      
  31.             } catch (InterruptedException e) {      
  32.                 e.printStackTrace();      
  33.             }      
  34.         }      
  35.     };      
  36.      
  37.     /**    
  38.      * 实现<code>InitializingBean</code>接口,在完成注入后调用启动索引线程.  
  39.      */     
  40.     public void afterPropertiesSet() throws Exception {      
  41.         if (buildIndex) {      
  42.             indexThread.setDaemon(true);      
  43.             indexThread.setName("Compass Indexer");      
  44.             indexThread.start();      
  45.         }      
  46.     }      
  47.      
  48.     public void setBuildIndex(boolean buildIndex) {      
  49.         this.buildIndex = buildIndex;      
  50.     }      
  51.      
  52.     public void setLazyTime(int lazyTime) {      
  53.         this.lazyTime = lazyTime;      
  54.     }      
  55.      
  56.     public void setCompassGps(CompassGps compassGps) {      
  57.         this.compassGps = compassGps;      
  58.     }      
  59. }   


实现了spring的InitializingBean接口,让服务器启动,bean初始化的时候去建立索引


剩下的就是配置文件了

Java代码 复制代码
  1. <?xml version="1.0" encoding="UTF-8"?>   
  2.   
  3. <beans xmlns="http://www./schema/beans"  
  4.     xmlns:xsi="http://www./2001/XMLSchema-instance"  
  5.     xmlns:aop="http://www./schema/aop"  
  6.     xmlns:tx="http://www./schema/tx"  
  7.     xsi:schemaLocation="http://www./schema/beans http://www./schema/beans/spring-beans-2.5.xsd   
  8.             http://www./schema/aop http://www./schema/aop/spring-aop-2.5.xsd   
  9.             http://www./schema/tx http://www./schema/tx/spring-tx-2.5.xsd">   
  10.   
  11.     <bean id="annotationConfiguration"  
  12.         class="org.compass.annotations.config.CompassAnnotationsConfiguration">   
  13.     </bean>   
  14.   
  15.     <!-- compass Bean  -->   
  16.     <bean id="compass" class="org.compass.spring.LocalCompassBean">   
  17.         <property name="compassConfiguration"  
  18.             ref="annotationConfiguration" />   
  19.         <!-- 数据索引存储位置 -->   
  20.         <property name="connection">   
  21.             <value>/compass/indexes</value>   
  22.         </property>   
  23.         <property name="transactionManager" ref="transactionManager" />   
  24.         <property name="compassSettings">   
  25.             <props>   
  26.                 <prop key="compass.transaction.factory">   
  27.                     org.compass.spring.transaction.SpringSyncTransactionFactory   
  28.                 </prop>   
  29.                
  30.                 <prop   
  31.                     key="compass.engine.highlighter.default.formatter.simple.pre">   
  32.                     <![CDATA[<span style='background-color:yellow;color:red;'>]]>   
  33.                 </prop>   
  34.                 <prop   
  35.                     key="compass.engine.highlighter.default.formatter.simple.post">   
  36.                     <![CDATA[</span>]]>   
  37.                 </prop>   
  38.     <!--定义分词器-->             
  39. <prop   
  40.                     key="compass.engine.analyzer.default.type">   
  41.                     org.mira.lucene.analysis.IK_CAnalyzer   
  42.                 </prop>   
  43.             </props>   
  44.         </property>   
  45.         <property name="classMappings">   
  46.             <list>   
  47.                
  48.                 <value>cn.rgcenter.entity.Article</value>   
  49.             </list>   
  50.         </property>   
  51.     </bean>   
  52.   
  53.     <!--hibernate驱动-->   
  54.     <bean id="hibernateGpsDevice"  
  55.         class="org.compass.spring.device.hibernate.dep.SpringHibernate3GpsDevice">   
  56.         <property name="name">   
  57.             <value>hibernateDevice</value>   
  58.         </property>   
  59.         <property name="sessionFactory" ref="sessionFactory" />   
  60.         <property name="mirrorDataChanges">   
  61.             <value>true</value>   
  62.         </property>   
  63.     </bean>   
  64.   
  65.     <!-- 数据库中的数据变化后同步更新索引 -->   
  66.     <bean id="hibernateGps"  
  67.         class="org.compass.gps.impl.SingleCompassGps" init-method="start"  
  68.         destroy-method="stop">   
  69.         <property name="compass">   
  70.             <ref bean="compass" />   
  71.         </property>   
  72.         <property name="gpsDevices">   
  73.             <list>   
  74.                 <bean   
  75.                     class="org.compass.spring.device.SpringSyncTransactionGpsDeviceWrapper">   
  76.                     <property name="gpsDevice" ref="hibernateGpsDevice" />   
  77.                 </bean>   
  78.             </list>   
  79.         </property>   
  80.     </bean>   
  81.   
  82.     <!-- compass模版 -->   
  83.     <bean id="compassTemplate"  
  84.         class="org.compass.core.CompassTemplate">   
  85.         <property name="compass" ref="compass" />   
  86.     </bean>   
  87.   
  88.     <!-- 定时重建索引(利用quartz)或随Spring ApplicationContext启动而重建索引 -->   
  89.     <bean id="compassIndexBuilder"  
  90.         class="cn.rgcenter.compass.service.CompassIndexBuilder"  
  91.         lazy-init="false">   
  92.         <property name="compassGps" ref="hibernateGps" />   
  93.         <property name="buildIndex" value="true" />   
  94.         <property name="lazyTime" value="5" />   
  95.     </bean>   
  96.   
  97.     <!-- 搜索引擎服务类 -->   
  98.     <bean id="searchService"  
  99.         class="cn.rgcenter.compass.service.SearchServiceBean">   
  100.         <property name="compass">   
  101.             <ref bean="compass" />   
  102.         </property>   
  103.     </bean>   
  104.   
  105.     <!-- 搜索引擎Action -->   
  106.     <bean id="searchAction" class="cn.rgcenter.action.SearchAction">   
  107.         <property name="searchService">   
  108.             <ref bean="searchService" />   
  109.         </property>   
  110.     </bean>   
  111.   
  112. </beans>  


至于action就不列出代码了,很简单了,只需要传搜索方法的那几个参数过去就可以了.

最后看一下搜索结果示例图:

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多