1、Compass簡單介紹
Compass是一個強大的,事務的,高性能的對象/搜索引擎映射(OSEM:object/searchengine mapping)與一個Java持久層框架。
Compass包括以下功能:
* 搜索引擎抽象層(使用Lucene搜索引薦),
* OSEM (Object/Search Engine Mapping) 支持,
* 事務管理,
* 類似於Google的簡單關鍵字查詢語言,
* 可擴展與模塊化的框架,
* 簡單的API.
2、Compass的優點與缺點
優點:
* Compass將lucene、Spring、Hibernate三者的起來,以很低很低的成本快速實現企業應用中的搜索功能;
* Compass比較成熟,網上的文檔很多,入門很簡單;
* 更多優點
缺點:
* Compass目前版本是2.2.0,已經很久沒有更新與維護。Compass2.2的版本所對應的Lucene2.4.1,但現在Lucene已經升級到3以上的版本,Lucene3以上的版本的API差別很大,3.0以後版本貌似效率更高
* 說這麼多最終目的是說Compass目前只支持到Lucene2.4.1版本,如果你想使用Lucene就不能使用Compass了
* 現在已經有Hibernate Search作爲搜索引擎框架,可以與Lucene進行聯合使用。但我沒有真正的去使用過。
3、Compass
Compass 通過OSEM(Object/Search Engine Mapping)允許把應用對象的領域模型映射到搜索引擎,目前有兩種方式來進行OSEM,分別是XML方式和JDK5以上的註解(Annotation)
方式。
與採用xml配置文件相比較,採用Annonation方式還是相對簡單。使用註解方式核心標註只有@Searchable、@SearchableId、@SearchableProperty、 @SearchableComponent個,很容易記憶,
不想XML那麼麻煩,尤其是和spring、hiberante一起使用時,建議採用註解方式。
(1)、註解詳細信息
@Searchable、@SearchableId、@SearchableProperty、 @SearchableComponent分別代表搜索類、主鍵、可搜索的屬性與關聯的、另一個可搜索的對象
(注:Compass要求POJO要有默認構造函數,要實現equals()和hashcode()):
(a)、@Searchable
如:
@Searchable
public class Article {
(b)、@SearchableId
如:
@SearchableId
privateString id;
也可以這樣寫
@SearchableId
publicInteger getId() {
returnthis.id;
}
(c)、@SearchableProperty
@SearchableProperty(name="name", store=Store.NA)
privateString name;
也可以放在該屬性的getter方法的前
@SearchableProperty註解有幾個屬性需要注意:
store:
Store.NA,默認值,等同Store.YES
Store.NO 與Lucene中的Field.Store.NO;指定不存儲域值
Store.YES 與Lucene中的Field.Store.YES;指定存儲域值
Store.COMPRESS
index:
Index.NA:
Index.NO:使對應的域值不進行搜索
INDEX.ANALYZED:對域進行索引,並將域值分解成對應的詞彙單元,並使每個詞彙單元能被搜索
INDEX.NOT_ANALYZED:對域進行索引,但不對string值進行分析
boost:域的加權
其它的可以仔細瞭解
(2)、Compass核心API
Compass的核心API借鑑了Hibernate的術語,因此在操作上基本上與Hibernate類似,以下爲Compass的幾個核心接口:
CompassConfiguration(類似Hibernate Configuration):用來在一些設置參數、配置文件和映射定義上配置Compass。通常用來創建Compass接口。
Compass(類似Hibernate SessionFactory):爲單線程使用,創建線程安全的實例來打開CompassSeesion。同樣還提供了一些搜索引擎索引級別的操作。
CompassSesssion(類似Hibernate Session):用來執行像保存、刪除、查找、裝載這樣的搜索操作。很輕量但是並不是線程安全的。
CompassTransaction(類似HibernateTransaction):管理Compass事務的接口。使用它並不需要事務管理環境(像Spring、JTA)。
Compass和Hibernate很相像,無非就是Hibernate把JDBC封裝了一把.所以從結構上來說,只要我們瞭解了Hibernate,就已經對Compass有了瞭解.那麼Hibernate需要提供API和配置文件來對JDBC進行操作,那麼Compass呢?Compass不僅從結構上模仿了Hibernate,就連API風格也不盡相同.我們把它和Hibernate的API做個對比就知道了:
再把兩個session的核心方法比較一下:
Hibernate session API |
CompassSession API |
|
save(Object) |
create(Object) |
建立索引 |
saveOrUpdate(Object) |
save(Object) |
保存或更新 |
delete(Object) |
delete(Class, ids...) |
刪除索引 |
get() |
get() |
獲取 |
createQuery(hql).list() |
find(String) |
使用查詢字符串查詢 |
所以說,Compass與Hibernate極爲相似,Compass總結起來就兩句話:
4、Compass、Lucene、Spring、Hibernate集成
可以不爲compass編寫一行代碼或者很少的代碼,就可以做完搜索引擎的檢索
使用Lucene2.4.1;Compass2.2.0
- <!-- 使用annotation配置,指定要轉換的POJO。PO類在compass的classMappings值指定 -->
- <bean id="annotationConfiguration"
- class="org.compass.annotations.config.CompassAnnotationsConfiguration">
- </bean>
- <bean id="compass" class="org.compass.spring.LocalCompassBean">
- <!-- OSEM映射的對象PO類 -->
- <property name="classMappings">
- <list>
- <value>com.core.persistence.po.Article</value>
- <value>com.core.persistence.po.Author</value>
- </list>
- </property>
- <!-- 使用註解配置 -->
- <property name="compassConfiguration" ref="annotationConfiguration"/>
- <property name="compassSettings">
- <props>
- <!-- 索引文件在服務器上的存儲路徑 如:file://d:/index -->
- <prop key="compass.engine.connection">/lucene/indexes</prop>
- <!-- 在內存中建立索引
- <prop key="compass.engine.connection">ram://index</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="compassTemplate" class="org.compass.core.CompassTemplate">
- <property name="compass" ref="compass"/>
- </bean>
- <!-- 與hibernate的綁定,經Hiberante的數據改變會自動被反射到索引裏面(增加、修改、刪除操作). -->
- <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>
- <ref local="hibernateGpsDevice"/>
- </list>
- </property>
- </bean>
- <!-- 定時重建索引(利用quartz)或隨Spring ApplicationContext啓動而重建索引 -->
- <bean id="compassIndexBuilder" class="com.lucene.service.CompassIndexBuilder" lazy-init="false">
- <property name="compassGps" ref="compassGps"/>
- <property name="buildIndex" value="true"/>
- <property name="lazyTime" value="10"/>
- </bean>
- public class CompassIndexBuilder implements InitializingBean {
- private static final Logger log = Logger.getLogger(CompassIndexBuilder.class);
- // 是否需要建立索引,可被設置爲false使本Builder失效.
- private boolean buildIndex = true;
- // 索引操作線程延時啓動的時間,單位爲秒
- private int lazyTime = 10;
- // Compass封裝
- private CompassGps compassGps;
- // 索引線程
- private Thread indexThread = new Thread() {
- @Override
- public void run() {
- try {
- Thread.sleep(lazyTime * 1000);
- log.info("begin compass index...");
- long beginTime = System.currentTimeMillis();
- // 重建索引.
- // 如果compass實體中定義的索引文件已存在,索引過程中會建立臨時索引,
- // 索引完成後再進行覆蓋.
- compassGps.index();
- long costTime = System.currentTimeMillis() - beginTime;
- log.info("compss index finished.");
- log.info("costed " + costTime + " milliseconds");
- } catch (InterruptedException e) {
- }
- }
- };
- /**
- * 實現<code>InitializingBean</code>接口,在完成注入後調用啓動索引線程.
- * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
- */
- public void afterPropertiesSet() throws Exception {
- if (buildIndex) {
- indexThread.setDaemon(true);
- indexThread.setName("Compass Indexer");
- indexThread.start();
- }
- }
- public void setBuildIndex(boolean buildIndex) {
- this.buildIndex = buildIndex;
- }
- public void setLazyTime(int lazyTime) {
- this.lazyTime = lazyTime;
- }
- public void setCompassGps(CompassGps compassGps) {
- this.compassGps = compassGps;
- }
- }
5、進行簡單搜索
- Compass compass = compassTemplate.getCompass();
- CompassSession session=compass.openSession();
- List list = new ArrayList();
- CompassHits hits= session.queryBuilder().queryString(queryString).toQuery().hits();
- for(int i=0;i<hits.length();i++){
- Person hit=( Person)hits.data(i);
- list.add(hit);
- }
- session.close();
- return list;
以上內容有參考他人之處,不在這列出,謝謝!