首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 开源软件 >

应用Compass实现搜索功能

2013-01-07 
使用Compass实现搜索功能1前言Compass 是一个功能强大、支持事务的JAVA搜索引擎框架。Compass允许将对象域模

使用Compass实现搜索功能
1前言

Compass 是一个功能强大、支持事务的JAVA搜索引擎框架。Compass允许将对象域模型映射到搜索引擎,并能同步搜索引擎索引和数据源。Compass 在低级别的 Lucene API的基础上提供了更高级别的抽象。同时Compass实现了快速索引操作和优化,并使搜索引擎具有事务处理能力。

本文档介绍在SSH(struts+spring+hibernate)环境下配置和使用Compass的方法。
2 下载compass包

创建JAVA web工程,并导入struts、spring、hibernate所需的JAR文件及配置文件。

从官方网站http://www.compass-project.org下载Compass软件包:compass-2.2.0-with-dependencies.zip。解开压缩文件后,将compass-2.2.0.jar和lucene-core-2.4.1.jar添加到项目的Build Path中。
3 OSEM - Object/Search Engine Mapping

Compass 通过使用Java 5 注解或者简单的XML映射文件将Java对象映射到搜索引擎。

这种技术就是OSEM (Object Search Engine Mapping)。Compass 使用OSEM从对象中抽取需要的属性,并将需要的元数据插入到搜索引擎索引中。本文采用XML文件来描述对象和搜索引擎的关系。

1.   域模型的POJO

下面是一个Java POLO类。

public class Book implements java.io.Serializable {    // Fields    private long bookId;    private String bookName;    private String isbn;    private String publisher;    private String author;    private long currentStock;    private long safeStock;    private Double price;    private String memo;    // 方法略}


2.   OSEM XML映射定义

Book.cpm.xml文件的内容:
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE compass-core-mapping PUBLIC    "-//Compass/Compass Core Mapping DTD 2.2//EN"    "http://www.compass-project.org/dtd/compass-core-mapping-2.2.dtd"><compass-core-mapping package="cn.ittrain.tcrm.domain"><class name="Book" alias="${mybooks.book}">   <id name="bookId" />   <property name="bookName">    <meta-data>${mybooks.bookName}</meta-data>   </property>   <property name="isbn">    <meta-data>${mybooks.isbn}</meta-data>   </property>   <property name="publisher">    <meta-data>${mybooks.publisher}</meta-data>   </property>   <property name="author">    <meta-data>${mybooks.author}</meta-data>   </property>   <property name="currentStock">    <meta-data>${mybooks.currentStock}</meta-data>   </property>   <property name="safeStock">    <meta-data>${mybooks.safeStock}</meta-data>   </property>   <property name="price">    <meta-data>${mybooks.price}</meta-data>   </property>   <property name="memo">    <meta-data>${mybooks.memo}</meta-data>   </property></class></compass-core-mapping>

其中的元数据名和别名在下面的元数据文件中定义,Compass会自动用元数据名和别名的值来替换${}。

3.   元数据(Meta data)定义

公共元数据文件定义在OSEM映射文件中使用的元数据名和别名。

每一个类的映射定义都在一个别名下注册。别名是类的OSEM定义和类本身之间的桥梁。可以使用别名来引用一个类的映射定义。

元数据把映射定义中属性的值按照名称保存到索引中。

Book.cmd.xml文件的内容:
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE compass-core-meta-data PUBLIC    "-//Compass/Compass Core Meta Data DTD 2.2//EN"    "http://www.compass-project.org/dtd/compass-core-meta-data-2.2.dtd"><compass-core-meta-data><meta-data-group id="mybooks" displayName="Mybooks Meta Data">   <description>Book Meta Data</description>   <uri>http://compass/mybooks</uri>   <alias id="book" displayName="Book">    <description>Book alias</description>    <uri>http://compass/mybooks/Book</uri>    <name>book</name>   </alias>     <meta-data id="bookId" displayName="BookId">    <description>BookId alias</description>    <uri>http://compass/mybooks/bookId</uri>    <name>bookId</name>   </meta-data>   <meta-data id="bookName" displayName="BookName">    <description>BookName alias</description>    <uri>http://compass/mybooks/bookName</uri>    <name>bookName</name>   </meta-data>   <meta-data id="isbn" displayName="isbn">    <description>isbn alias</description>    <uri>http://compass/mybooks/isbn</uri>    <name>isbn</name>   </meta-data>    <meta-data id="publisher" displayName="Publisher">    <description>Publisher alias</description>    <uri>http://compass/mybooks/publisher</uri>    <name>publisher</name>   </meta-data>   <meta-data id="author" displayName="Author">    <description>Author alias</description>    <uri>http://compass/mybooks/author</uri>    <name>author</name>   </meta-data>   <meta-data id="currentStock" displayName="CurrentStock">    <description>CurrentStock alias</description>    <uri>http://compass/mybooks/currentStock</uri>    <name>currentStock</name>   </meta-data>   <meta-data id="safeStock" displayName="SafeStock">    <description>SafeStock alias</description>    <uri>http://compass/mybooks/safeStock</uri>    <name>safeStock</name>   </meta-data>   <meta-data id="price" displayName="Price">    <description>Price alias</description>    <uri>http://compass/mybooks/price</uri>    <name>price</name>   </meta-data>   <meta-data id="memo" displayName="Memo">    <description>Memo alias</description>    <uri>http://compass/mybooks/memo</uri>    <name>memo</name>   </meta-data></meta-data-group></compass-core-meta-data>


4 Hibernate配置

对3.1节中Book配置Hibernate的映射文件:Book.hbm.xml。
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping>    <class name="cn.ittrain.tcrm.domain.Book" table="BOOK" schema="LIXIANZHU">        <id name="bookId" type="long">            <column name="BOOK_ID" precision="22" scale="0" />            <generator />        </id>        <property name="bookName" type="java.lang.String">            <column name="BOOK_NAME" length="50" />        </property>        <property name="isbn" type="java.lang.String">            <column name="ISBN" length="20" />        </property>        <property name="publisher" type="java.lang.String">            <column name="PUBLISHER" length="50" />        </property>        <property name="author" type="java.lang.String">            <column name="AUTHOR" length="20" />        </property>        <property name="currentStock" type="long">            <column name="CURRENT_STOCK" precision="22" scale="0" />        </property>        <property name="safeStock" type="long">            <column name="SAFE_STOCK" precision="22" scale="0" />        </property>        <property name="price" type="java.lang.Double">            <column name="PRICE" precision="126" scale="0" />        </property>        <property name="memo" type="java.lang.String">            <column name="MEMO" />        </property>          </class></hibernate-mapping>


5 Spring配置

1.       在配置Compass 相关的bean之前,必须先配置SessionFactory和TransactionManager:
<bean id="sessionFactory"         ref="sessionFactory"/>    </bean> 


2.   配置Compass。Compass用来实现搜索功能。

<bean id="compass" ref="txManager"/>    </bean> 


3.   配置CompassGps。CompassGps用来实现索引功能。
 <!-- 与hibernate的绑定,用Hibernate 3 事件系统,支持Real Time Data Mirroring .    经Hiberante的数据改变会自动被反射到索引里面.  --><bean id="hibernateGpsDevice" ref="sessionFactory"/>    </bean>         <bean id="compassGps" init-method="start" destroy-method="stop">      <property name="compass" ref="compass"/>      <property name="gpsDevices">      <list>         <ref local="hibernateGpsDevice"/>      </list>      </property>     </bean>


4.   配置CompassSearchCommand和CompassSearchHelper。CompassSearchCommand存储搜索命令,CompassSearchHelper执行搜索查询。

<bean id="compassSearchCommand" /> <!-- 每页的条数 -->         <constructor-arg ref="compass" /></bean>


6 配置Action

SearchAction用来建立索引和搜索。indexControl方法建立索引,而searchControl方法执行搜索。SearchAction以及compassGps、compassSearchCommand、compassSearchHelper由Spring依赖注入,其在Spring配置文件中的声明不在此赘述。

public class SearchAction extends DispatchAction {    private static final Log log = LogFactory.getLog(SearchAction.class);    private CompassGps compassGps;    private CompassSearchCommand compassSearchCommand;      private CompassSearchHelper compassSearchHelper;    // Setter 方法略     public ActionForward indexControl(ActionMapping mapping, ActionForm form,             HttpServletRequest request, HttpServletResponse response) {         compassGps.start();         compassGps.index();         return null;    }       public ActionForward searchControl(ActionMapping mapping, ActionForm form,             HttpServletRequest request, HttpServletResponse response) {         String query = request.getParameter("query");                String page = request.getParameter("page");         Integer pageFrom = (page == null || page.length() == 0) ? 0:Integer.valueOf(page);         compassSearchCommand.setQuery(query);         compassSearchCommand.setPage(pageFrom);         CompassSearchResults searchResults= compassSearchHelper.search(compassSearchCommand);         String commandQuery = compassSearchCommand.getQuery();         request.setAttribute("status", commandQuery);         request.setAttribute("searchResults", searchResults);         return mapping.findForward("searchResults");    }}


7 搜索页面
<body>  <FORM method="GET" action="search.do">    <INPUT type="text" size="20" name="query" value="<c:out value="${status}"/>" />    <input type="hidden" name="method" value="searchControl"/>   <INPUT type = "submit" value="Search"/>  </FORM> <c:if test="${! empty searchResults}">   搜索花费 <c:out value="${searchResults.searchTime}" />毫秒  搜索关键字:<c:out value="${status}"/>  <c:forEach var="hit" items="${searchResults.hits}">   <c:choose>     <c:when test="${hit.alias == 'book'}">       <P>         BookId:<a href="<c:url value="/editPet.htm?petId=${hit.data.bookId}"/>">           ${hit.data.bookId}         </a>         BookName:<c:out value="${hit.data.bookName}" />         Publisher:<c:out value="${hit.data.publisher}" />         ISBN:<c:out value="${hit.data.isbn}" />        <br/>            </c:when>   </c:choose>  </c:forEach>   <c:if test="${! empty searchResults.pages}">    <BR><BR><BR>    <table><tr>    <c:forEach var="page" items="${searchResults.pages}" varStatus="pagesStatus">      <td>      <c:choose>        <c:when test="${page.selected}">          <c:out value="${page.from}" />-<c:out value="${page.to}" />        </c:when>        <c:otherwise>         <FORM method="GET" action="search.do">              <INPUT type="hidden" name="query" value="<c:out value="${status}"/>" />    <INPUT type="hidden" name="page" value="<c:out value="${pagesStatus.index}"/>" />                   <input type="hidden" name="method" value="searchControl"/>           <INPUT type = "submit" value="<c:out value="${page.from}" />-<c:out value="${page.to}" />"/>          </FORM>        </c:otherwise>      </c:choose>      </td>    </c:forEach>    </tr></table>  </c:if></c:if>  </body>

热点排行