- 1.概述
- Compass将lucene、Spring、Hibernate三者的起来,以很低很低的成本快速实现企业应用中的搜索功能。
- HomePage: http://www.opensymphony.com/compass/
- springside里用了compass来做图书搜索,快速建立的流程如下:
- 1.用简单的compass annotation把Book对象映射到Lucene。
- 2.配置compass默认提供的基于Spring MVC的Index Controller 和Search Controller。
- 3.编写查询结果的显示页面,将controller返回的变量显示出来。
- 2.Object/Search Engine Mapping的 Annotations配置
- 使用JDK5 的annotation 来进行OSEM(Object/Search Engine Mapping)比用xml文件按简单许多,下面就是简单的搜索类,可见@SearchableID, @SearchableProperty与@SearchableComponent 三个标记,分别代表主键、可搜索的属性与关联的,另一个可搜索的对象,另外Compass要求POJO要有默认构造函数,要实现equals()和hashcode():
- 详细请点击查看springside中的Product.java , Book.java, Category.java
- public class Product {
- @SearchableId
- private Integer id;
- private Category category;
- private String name;
- private Double unitprice;
- @SearchableProperty(name = "name")
- public String getName() { return this.name; }
- @SearchableComponent (refAlias = "category")
- public Category getCategory() { return this.category; }
- public Double getUnitprice() { return this.unitprice; }
- 3. 与spring,hibernate集成配置
- 3.1 spring配置文件
- hiberante中的sessionFactory,transactionManager相比大家也是轻车熟路了.compass已经对对spring集成做了很好的封装,让我们的使用更加简单,我们可以不为compass编写一行代码,就可以做完搜索引擎的检索.下面是compass在spring中的简明配置. 详情点击查看springside中的applicationContext-lucene.xml :
- <beans>
- <bean id="annotationConfiguration" class="org.compass.annotations.config.CompassAnnotationsConfiguration"></bean>
- <bean id="compass" class="org.compass.spring.LocalCompassBean">
- <!-- anontaition式设置 -->
- <property name="classMappings">
- <list>
- <value>org.springside.bookstore.domain.Book</value>
- </list>
- </property>
- <property name="compassConfiguration" ref="annotationConfiguration"/>
- <property name="compassSettings">
- <props>
- <prop key="compass.engine.connection">file://${user.home}/springside/compass</prop>
- <prop key="compass.transaction.factory">org.compass.spring.transaction.SpringSyncTransactionFactory</prop>
- </props>
- </property>
- <property name="transactionManager" ref="transactionManager"/>
- </bean>
- <bean id="hibernateGpsDevice" class="org.compass.spring.device.hibernate.SpringHibernate3GpsDevice">
- <property name="name">
- <value>hibernateDevice</value>
- </property>
- <property name="sessionFactory" ref="sessionFactory"/>
- </bean>
- <bean id="compassGps" class="org.compass.gps.impl.SingleCompassGps" init-method="start" destroy-method="stop">
- <property name="compass" ref="compass"/>
- <property name="gpsDevices">
- <list>
- <ref local="hibernateGpsDevice"/>
- </list>
- </property>
- </bean>
- </beans>
- 上面要留意的配置有:
- annotationConfiguration: 使用annotation配置,指定要转换的POJO如Book
- compass.engine.connection : 索引文件在服务器上的存储路径.
- hibernateGpsDevice: 与hibernate的绑定,用Hibernate 3 事件系统,支持Real Time Data Mirroring .经Hiberante的数据改变会自动被反射到索引里面.
- 3.2 web Controller的配置
- 两个Controller都是现成的,只要配置相关选项即可。
- 详情请查看springside的bookstore-servlet.xml
- <bean id="indexBookController" class="org.compass.spring.web.mvc.CompassIndexController">
- <property name="compassGps" ref="compassGps"/>
- <property name="indexView" value="/admin/indexBook.jsp"/>
- <property name="indexResultsView" value="/admin/indexBook.jsp"/>
- </bean><bean id="searchBookController" class="org.compass.spring.web.mvc.CompassSearchController">
- <property name="compass" ref="compass"/>
- <propertyname="searchView"value="/home/top.jsp"/>
- <property name="searchResultsView" value="/home/searchBook.jsp"/>
- <property name="pageSize" value="5"/></bean>
- 3.3 View JSP
- 简单搜索页面:只需要一个query 参数:
- <INPUT type="text" size="20" name="query">
- 结果页面:
- 结果页面将返回几个变量,包括:
- searchResults(搜索结果) 包括hits(结果)和 searchtime(耗时)
- pages(分页信息) 包括page_from page_to等
- command(原来的查询请求)
- 具体使用见springside的advancedSearch.jsp ,下面是简版的代码:
- <c:if test="${not empty searchResults}"> 耗时:
- <c:out value="http://www.zhmy.com/${searchResults.searchTime}"/>ms
- <c:forEach var="hit" items="${searchResults.hits}">
- <c:choose>
- <c:when test="${hit.alias == 'book'}">
- <div class="left_content">
- <a href="#" class= "title"> 《${hit.data.name}》</a> <br/> 作者:${hit.data.author}<br/>
- </div>
- </c:when>
- </c:choose>
- </c:forEach></c:if>
- 4.扩展高级搜索
- 扩展高级搜索其实很简单,SpringSide已经初步封装了加入包含以下任意单词,不包含以下任何单词,分类选择等条件及每页显示条数的确定。
- 如果需要更多条件:
- 1. 加强搜索页面,加入更多条件的显示。
- 2. 扩展compass的command class,接受从搜索条件页传过来的条件。 可从springside的AdvancedSearchCommand 扩展或从Compass的原类扩展。
- 3. 扩展compass的searchController, 将command中的变量重新处理为一个符合Lucene语法规则的query变量 即可(见springside中的AdvancedSearchController ),同时可以为搜索条件页查询图书分类列表一类的变量。
- 你可以从springside的AdvancedSearchController扩展,重载onSetupCommand (),参考父类的做法,加装自己的条件。重载referenceData(),把图书分类列表这种条件加入到AdvancedSearchCommand 的referenceData Map中供搜索条件页显示,例子见BookSearchController。
- 也可以参考BookSearchController和AdvancedSearchController的做法,完全自行扩展。
- 其实compass只是简单的应用的话,也很容易上手的
- 假如使用了hibernate+spring+compass
- 关于compass在spring中的配置如下,保存为一个xml文件,在web.xml中引入即可
- Java代码
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
- <beans>
- <bean id="annotationConfiguration" class="org.compass.annotations.config.CompassAnnotationsConfiguration"></bean>
- <bean id="compass" class="org.compass.spring.LocalCompassBean">
- <!-- 这里的配置意思是指需要搜索的POJO对象 -->
- <property name="classMappings">
- <list>
- <value>com.tourye.model.TnInfomation</value>
- </list>
- </property>
- <!-- 这里的配置意思是指使用annotation进行compass配置 -->
- <property name="compassConfiguration" ref="annotationConfiguration" />
- <property name="compassSettings">
- <props>
- <prop key="compass.engine.connection">/home/dev/compass</prop>这里说明索引文件所放的目录
- <prop key="compass.transaction.factory">org.compass.spring.transaction.SpringSyncTransactionFactory</prop>
- <!-- <prop key="compass.engine.analyzer.default.type">net.paoding.analysis.analyzer.PaodingAnalyzer</prop> -->这里的注释是为了说明使用paoding的分词器,由于测试时,有时会出问题,所以暂时禁用
- </props>
- </property>
- <property name="transactionManager">
- <ref bean="transactionManager" />
- </property>
- <!--
- 高亮设置,未测试成功,需要相关的代码辅助 <property name="compass.engine.highlighter.default.formatter.simple.pre"> <value><![CDATA[<font
- color="red"><b>]]></value> </property> <property name="compass.engine.highlighter.default.formatter.simple.post">
- <value><![CDATA[</b></font>]]></value> </property>
- -->
- </bean>
- 下面的两段配置是为了说明compass构建索引与hibernate的insert/delete/update操作同步
- <bean id="hibernateGpsDevice" class="org.compass.gps.device.hibernate.HibernateGpsDevice">
- <property name="name">
- <value>hibernateDevice</value>
- </property>
- <property name="sessionFactory">
- <ref bean="mySessionFactory" />
- </property>
- <property name="nativeExtractor">
- <bean class="org.compass.spring.device.hibernate.SpringNativeHibernateExtractor" />
- </property>
- </bean>
- <bean id="compassGps" 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>
- <!-- 自动随Spring ApplicationContext启动而重建索引,未研究 -->
- <bean id="compassIndexBuilder" class="com.tourye.service.timer.CompassIndexBuilder" lazy-init="false">
- <property name="compassGps" ref="compassGps" />
- <property name="buildIndex" value="true" />
- <property name="lazyTime" value="10" />
- </bean>
- </beans>
- 第二步:
- 使用annotatio声明要索引的object,如下所示,自己根据需要进行设置
- Java代码
- @Searchable
- public class TnInfomation implements java.io.Serializable {
- private static final long serialVersionUID = -4503017770118428686L;
- @SearchableId(name = "id")
- private Long id;
- private int type;
- @SearchableProperty(name="title")
- private String title;
- @SearchableProperty(name="keywords")
- private String keywords;
- @SearchableProperty(name="content")
- private String content;
- private int author;
- private Date createtime;
- private Date updatetime;
- @SearchableProperty(name="approvetime")
- private Date approvetime;
- private int clicks;
- private int critiques;
- private String provenance;
- @SearchableProperty(name="status")
- private byte status; /* 待审核(0) 已审核(1)*/
- 第三步,建立搜索service
- Java代码
- public class InfomationSearchServiceImpl implements InfomationSearchService {
- private Compass compass;
- public Compass getCompass() {
- return compass;
- }
- public void setCompass(Compass compass) {
- this.compass = compass;
- }
- /*
- * (non-Javadoc)
- *
- * @see
- * com.tourye.infomation.compass.InfomationSearchService#search(java.lang
- * .String, int, int)
- */
- public CompassSearchResults search(String query, int page, int pageSize) throws Exception {
- CompassSession session = compass.openSession();
- try {
- session.beginTransaction();
- //构建compass查询编辑器
- CompassQueryBuilder querybuilder = session.queryBuilder();
- CompassQuery cq = null;
- CompassSearchCommand csc = null;
- //声明查询条件,query是查询字符串
- if (StringUtils.isNotEmpty(query)) {
- cq = querybuilder.bool().addMust(querybuilder.spanEq("status", 1)).addMust(
- querybuilder.queryString(query).toQuery()).toQuery();
- cq.addSort("approvetime", CompassQuery.SortDirection.REVERSE);
- csc = new CompassSearchCommand(cq, new Integer(Math.max(0, page - 1)));
- } else {
- csc = new CompassSearchCommand(query.trim());
- }
- // 搜索命令InfomationSearchHelper和CompassSearchHelper相同,自己可以实现
- InfomationSearchHelper searchHelper = new InfomationSearchHelper(compass, pageSize);
- CompassSearchResults searchResults = searchHelper.search(csc);
- return searchResults;
- } finally {
- if (session != null) session.close();
- }
- }
- }
Compass将lucene、Spring、Hibernate三者结合
最新推荐文章于 2024-09-17 12:00:25 发布