compass搜索引擎的应用

前阵子在做一个手机服务器端系统的开发,主要使用spring+hibernate框架,由于系统涉及到全文检索功能,所以很自然地就想到了compass这个开源的搜索引擎,并且在j2ee领域,个人觉得目前最好用的就是这个了。为了提高系统的性能,我们大量的使用了compass创建的索引来做数据查询,因为我们主要功能是数据查询,很少做数据的更改,所以比较适合用这种方式,也收到了很好的效果。

首先是spring与compass的集成配置文件:applicationContext-compass.xml

Xml代码   收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.     xmlns:context="http://www.springframework.org/schema/context"  
  5.     xsi:schemaLocation="http://www.springframework.org/schema/beans   
  6.                 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"  
  7.         default-lazy-init="true">      
  8.       
  9.     <!-- 配置compass注解 -->  
  10.     <bean id="annotationConfiguration" class="org.compass.annotations.config.CompassAnnotationsConfiguration">  
  11.     </bean>  
  12.     <!-- 配置compass bean -->  
  13.     <bean id="compass" class="org.compass.spring.LocalCompassBean">  
  14.         <!-- 定义索引存放路径 -->  
  15.         <property name="connection">  
  16.           <value>file://${index.path}</value>  
  17.         </property>  
  18.         <!-- 配置需要创建索引的实体 -->  
  19.         <property name="classMappings">  
  20.           <list>          
  21.              <value>com.***.mobile.entity.KnowledgeInfo</value>  
  22.              <value>com.***.mobile.entity.ChannelInfo</value>  
  23.              <value>com.***.mobile.entity.MobileBaseEntity</value>  
  24.              <value>com.***.mobile.entity.BaseEntity</value>  
  25.              <value>com.***.mobile.entity.BusLine</value>  
  26.           </list>  
  27.         </property>  
  28.         <property name="compassConfiguration" ref="annotationConfiguration"></property>  
  29.         <property name="compassSettings">  
  30.          <props>  
  31.           <!-- compass事务工厂 -->  
  32.           <prop key="compass.transaction.factory">org.compass.spring.transaction.SpringSyncTransactionFactory</prop>  
  33.           <!-- paoding分词器 -->  
  34.           <prop key="compass.engine.analyzer.MMAnalyzer.CustomAnalyzer">net.paoding.analysis.analyzer.PaodingAnalyzer</prop>  
  35.           <!-- 设置高亮显示 -->  
  36.           <prop key="compass.engine.highlighter.default.formatter.simple.pre"><![CDATA[<font color="#cc0033"><b>]]></prop>   
  37.           <prop key="compass.engine.highlighter.default.formatter.simple.post"><![CDATA[</b></font>]]></prop>             
  38.          </props>  
  39.         </property>  
  40.         <property name="transactionManager" ref="transactionManager" />  
  41.     </bean>  
  42.     <!-- 用Hibernate3事件系统,支持Real Time Data Mirroring.经Hiberante改变的数据会自动被反射到索引里面 -->  
  43.     <bean id="hibernateGpsDevice" class="org.compass.gps.device.hibernate.dep.Hibernate3GpsDevice">  
  44.             <property name="name">  
  45.                     <value>hibernateDevice</value>  
  46.             </property>  
  47.             <property name="sessionFactory" ref="sessionFactory" />  
  48.             <property name="mirrorDataChanges">  
  49.                 <value>true</value>  
  50.             </property>  
  51.         </bean>  
  52.      <!-- 同步更新索引 -->  
  53.      <bean id="compassGps" class="org.compass.gps.impl.SingleCompassGps" init-method="start" destroy-method="stop">  
  54.     <property name="compass" ref="compass" />  
  55.     <property name="gpsDevices">  
  56.         <list>  
  57.             <bean class="org.compass.spring.device.hibernate.dep.SpringHibernate3GpsDevice">  
  58.                 <property name="name" value="hibernateDevice"/>  
  59.                 <property name="sessionFactory" ref="sessionFactory"/>  
  60.             </bean>  
  61.         </list>  
  62.     </property>  
  63.      </bean>  
  64.      <bean id="compassTemplate" class="org.compass.core.CompassTemplate">  
  65.         <property name="compass" ref="compass" />  
  66.           
  67.      </bean>  
  68. </beans>  

 接着是实体的compass注解,将需要创建索引的实体及实体属性标注:

Java代码   收藏代码
  1. @Entity  
  2. @Table(name="B_ENTITY_BASE")  
  3. @Searchable  
  4. public class MobileBaseEntity implements Serializable {  
  5.   
  6.     private static final long serialVersionUID = -5594658438463757978L;  
  7.   
  8.     @SearchableId  
  9.     protected String id;  
  10.     @SearchableProperty(name = "keys")  
  11.     protected String name;  
  12.     @SearchableProperty(index = Index.NO, store = Store.YES)  
  13.     protected String address;  
  14.     protected String phone;  
  15.     protected String description;  
  16.     @SearchableProperty(index = Index.NO, store = Store.YES)  
  17.     protected Double longitude;  
  18.     @SearchableProperty(index = Index.NO, store = Store.YES)  
  19.     protected Double latitude;  
  20.     @SearchableProperty(index = Index.NO, store = Store.YES)  
  21.     protected String type;  
  22.     protected String channel;  
  23.     protected String knowledgeId;  
  24.     protected String stauts;//0审核退回,1审核中,2正常  
  25. }  

@SearchableId:不要求定义搜索的元数据;

@SearchableProperty(name = "keys"):属性索引的别名,这个别名在做查询的时候会用到,我们可以把多个实体类的多个属性定义为同一个别名来做全文检索;

@SearchableProperty(index = Index.NO, store = Store.YES):保存这个属性的值,但不作为索引。index = Index.XXX,这个有几种策略,1:NOT_ANALYZED ,不分词但创建索引;2:ANALYZED,分词并创建索引。

@SearchableComponent:关联复合索引,用以复合类型;

@SearchableReference:用以引用类型。

接下来就是使用compass的API来做数据查询,首先是模糊匹配查询,

Java代码   收藏代码
  1. List<BusLine> busLineList = new ArrayList<BusLine>();  
  2.         Compass compass = this.compassTemplate.getCompass();  
  3.         CompassSession compassSession = compass.openSession();  
  4.         CompassQueryBuilder queryBuilder = compassSession.queryBuilder();  
  5.                                 //指定查询实体  
  6.         CompassQuery queryAlias = queryBuilder.alias(BusLine.class.getSimpleName());  
  7.         CompassBooleanQueryBuilder boolQueryBuilder = queryBuilder.bool();  
  8.         boolQueryBuilder.addMust(queryAlias);  
  9.         boolQueryBuilder.addMust(queryBuilder.wildcard("baseEntityKeys""*"+value+"*"));  
  10.         CompassHits compassHits = boolQueryBuilder.toQuery().hits();  
  11.         if(compassHits != null && compassHits.length() > 0) {  
  12.             for(int i = 0; i < compassHits.length(); i++) {  
  13.                 BusLine line = (BusLine)compassHits.data(i);  
  14.                 busLineList.add(line);  
  15.             }  
  16.         }  
  17.         compassSession.close();  
  18.         return busLineList;  

 至于是使用模糊匹配查询还是全文检索,这需要根据应用场景来选择,能使用模糊匹配的话尽量使用,全文检索的代价比模糊匹配要高。全文检索的例子:

Java代码   收藏代码
  1. String keywords = keyword.trim();  
  2. List<KnowledgeInfo> result = new ArrayList<KnowledgeInfo>();  
  3. Properties prop = PropertyUtil.readPropertyFile();  
  4. String type = prop.getProperty("knowledge.zc.type");  
  5. ChannelInfo channel = channelInfoService.getChannelById(type);  
  6. Compass compass = this.compassTemplate.getCompass();  
  7. CompassSession session = compass.openSession();  
  8. CompassQueryBuilder builder = session.queryBuilder();     
  9. CompassBooleanQueryBuilder boolBuidler = builder.bool();  
  10. boolBuidler.addMust(builder.wildcard("sort", channel.getSort()+"*"));  
  11. if(keywords != null && !"".equals(keywords)) {  
  12.     String[] array = keywords.split(" ");  
  13.     if (array != null && array.length > 0) {  
  14.         for (String value : array) {  
  15.             if (value != null && StringUtils.isNotEmpty(value.trim())) {  
  16.     boolBuidler.addMust(builder.queryString("keys:" + value).toQuery());  
  17.             }  
  18.         }  
  19.     }  
  20.     CompassHits hits = boolBuidler.toQuery().hits();  
  21.     if (hits != null && hits.length() > 0) {  
  22.         for (int i = 0; i < hits.length(); i++) {  
  23.             KnowledgeInfo info = (KnowledgeInfo) hits.data(i);  
  24.             String ht = hits.highlighter(i).fragment("keys");  
  25.             if (null != ht) {  
  26.                 info.setKeywords(ht);  
  27.             }  
  28.             result.add(info);  
  29.         }  
  30.     }  
  31. }  
  32. session.close();  
  33. return result;  

 compass一个简单的应用就完成了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值