在新架構中打算選擇Compass或Hibernate Search作為搜尋引擎架構,比較後,感覺Hibernate Search上還是沒有Compass成熟,另外考慮到後期對網頁的爬取及搜尋需求,決定還是基于Compass來作為架構預設的搜尋引擎。網上關于 Compass的文檔很多,但說得相對完整其詳細的入門文檔基本上沒有,Compass的官方文檔倒是說得很詳細,但是例子一塌糊塗,存在很大問題。記錄一下搭建的過程,作為入門的指南。
Compass 通過OSEM(Object/Search Engine Mapping)允許把應用對象的領域模型映射到搜尋引擎,最終通過通路common meta data來達到通路對象的目的。
1、幾個核心概念
1.1、annotation vs. xml配置檔案
Compass的配置檔案主要分成三類:
第一類:*.cmd.xml檔案*
.cmd.xml檔案是對common meta data進行定義,定義了最終搜尋的結果中的最基本的中繼資料。
第二類:*.cpm.xml檔案
*.cpm.xml是Object/Search Engine Mapping,提供了POJO到common meta data的映射。
第三類:*.cfg.xml檔案
Compass的*.cfg.xml定義了Compass的Index存放路徑、搜尋引擎分詞等相關資訊。
與采用xml配置檔案相比較,采用Annonation方式還是相對簡單,尤其是采用Spring時候,不用寫*.cmd.xml檔案、*.cpm.xml、*.cfg.xml,相對很友善,而且不像Hibernate的Annonation很多,Compass的 Annonation的核心标注隻有@Searchable、@SearchableId、@SearchableProperty、 @SearchableComponent個,很容易記憶。是以推薦使用Annonation方式
1.2、Compass核心API
Compass的核心API借鑒了Hibernate的術語,是以在操作上基本上與Hibernate類似,以下為Compass的幾個核心接口:
CompassConfiguration(類似Hibernate Configuration):用來在一些設定參數、配置檔案和映射定義上配置Compass。通常用來建立Compass接口。
Compass(類似Hibernate SessionFactory):為單線程使用,建立線程安全的執行個體來打開Compass Seesion。同樣還提供了一些搜尋引擎索引級别的操作。
CompassSesssion(類似Hibernate Session):用來執行像儲存、删除、查找、裝載這樣的搜尋操作。很輕量但是并不是線程安全的。
CompassTransaction(類似Hibernate Transaction):管理Compass事務的接口。使用它并不需要事務管理環境(像Spring、JTA)。
1.3、Compass與Spring內建
Compass 已經對對spring內建做了很好的封裝,同時與Spring對Hibernate的支援類似,Compass也提供了CompassTemplate來簡化諸如對Session、Transaction、Exception等操作,盡量充分使用此工具,可以有效提高效率。例如:
CompassTemplate ct = (CompassTemplate) context.getBean("compassTemplate");
Article article = new Article();
article.setTitle("Compass Test");
article.setPublishDate(new Date());
article.setAuthor(1);
ct.save(article); //存儲對象需要索引的資料到Compass的索引中。
2、軟體環境
Spring :2.5
Compas:1.2.1
Hibernate:3.2.5
Mysql :5.0.5
3、資料庫腳本
CREATE TABLE `article` (
`Id` int(11) NOT NULL auto_increment,
`title` varchar(40) NOT NULL default '',
`author` int(11) default '0',
`publish_date` date NOT NULL default '0000-00-00',
PRIMARY KEY (`Id`) ) TYPE=MyISAM;
CREATE TABLE `author` (
`Id` int(11) NOT NULL auto_increment,
`username` varchar(20) NOT NULL default '',
`password` varchar(20) NOT NULL default '',
`age` smallint(6) default '0',
PRIMARY KEY (`Id`) ) TYPE=MyISAM;
4、測試用例
從測試用例講起比較容易把關系理清楚,不然一堆術語和概念很讓人暈乎。
5、配置檔案
applicationContext-compass.xml
<?xml version="1.0"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN"
"http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans default-lazy-init="true">
<bean id="compassTemplate" class="org.compass.core.CompassTemplate">
<property name="compass" ref="compass"/>
</bean>
<bean id="annotationConfiguration"
class="org.compass.annotations.config.CompassAnnotationsConfiguration">
</bean>
<bean id="compass" class="org.compass.spring.LocalCompassBean">
<property name="classMappings">
<list>
<value>com.mobilesoft.esales.model.Article</value>
<value>com.mobilesoft.esales.model.Author</value>
</list>
</property>
<property name="compassConfiguration" ref="annotationConfiguration"/>
<property name="compassSettings">
<props>
<prop key="compass.engine.connection"> file://compass </prop>
<prop key="compass.transaction.factory">
org.compass.spring.transaction.SpringSyncTransactionFactory
</prop>
<prop
key="compass.engine.highlighter.default.formatter.simple.pre">
<![CDATA[<font color="red"><b>]]>
</prop>
<prop
key="compass.engine.highlighter.default.formatter.simple.post">
<![CDATA[</b></font>]]>
</prop>
</props>
</property>
<property name="transactionManager" ref="transactionManager"/>
</bean>
<bean id="hibernateGpsDevice"
class="org.compass.gps.device.hibernate.HibernateGpsDevice">
<property name="name">
<value>hibernateDevice</value>
</property>
<property name="sessionFactory" ref="sessionFactory"/>
<property name="mirrorDataChanges">
<value>true</value>
</property>
</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>
<bean
class="org.compass.spring.device.SpringSyncTransactionGpsDeviceWrapper">
<property name="gpsDevice" ref="hibernateGpsDevice"/>
</bean>
</list>
</property>
</bean>
<bean id="compassSearchService" class="com.mobilesoft.framework.search.service.CompassSearchService">
<property name="compass" ref="compass"/>
<property name="pageSize" value="15"/>
</bean>
<!-- 定時重建索引(利用quartz)或随Spring ApplicationContext啟動而重建索引 -->
<bean id="compassIndexBuilder" class="com.mobilesoft.framework.search.service.CompassIndexBuilder" lazy-init="false">
<property name="compassGps" ref="compassGps"/>
<property name="buildIndex" value="false"/>
<property name="lazyTime" value="10"/>
</bean>
</beans>
applicationContext-dao.xml、applicationContext-service.xml、applicationContext-resources.xml等略去。
6、Service層(參考了SpringSide實作)
8、Model層
@SearchableId 聲明Document的id列;
@SearchableProperty 聲明要索引的field;
@SearchableComponent 聲明要索引的其他關聯對象。
9、DAO層
ArticleDAO.java和AuthorDAO.java省略
直接用MyEclipse生成的,沒有什麼特别的。
10、參考文檔
http://www.compass-project.org/docs/1.2.1/reference/html/
The Compass Framework Search made easy.pdf
Compass TSSJS Europe 06.pdf
Hello World Tutorial
InfoQ: Compass: Integrate Search into your apps
InfoQ: Compass: Simplifying and Extending Lucene to Provide Google-like Search
InfoQ: Compass: 在你的應用中內建搜尋功能
Compass 指南
http://www.kimchy.org/
本文摘自:http://chuanliang2007.spaces.live.com/blog/cns!E5B7AB2851A4C9D2!389.entry