compass 介紹

Compass概念:
1:Compass相當於hibernate的SessionFactory
2:CompassSession相當於hibernate的Session
3:CompassTransaction相當於hibernate的transaction。

Compass 也是採用CompassConfiguration(裝載配置和映射文件)進行創建的。創建Compass時將會鏈接已經存在的索引或者創建一個新的索引。當Compass創建完後,就可以用compass得到compassSession。compassSession主要是起管理搜索引擎的數據。和 hb的SessionFactory一樣,compass通常在系統啓動時創建,在所有compassSession創建時使用。

當使用CompassSession查詢數據時,將會返回CompassHits接口的實例。compassHits可以得到 scores,resources和mapped objects.

Compass也提供了CompassTemplate和CompassCallback類處理會話和事務的處理。CompassTemplate template = new CompassTemplate(compass);

爲了簡化CompassConfiguration的建立,compass提供了CompassConfigurationFactory類來建立 CompassConfiguration
CompassConfiguration conf =CompassConfigurationFactory.newConfiguration();

除了通過xml文件設置外,可以通過CompassConfiguration.addXXX方法更改設置,也可以通過CompassSetting來設置。compassSetting和java 的Properties相似。也可以通過CompassEnvironment和LuceneEnvironment類來設置。

Compass中必須設置的項包括:compass.engine.connection。

一個重要的設置方面是組設置。如下面設置一個test的轉換器:
org.compass.converter.test.type=eg.TestConverter
org.compass.converter.test.param1=value1
org.compass.converter.test.param2=value2

所有的compass的操作性設置都可以定義在一個配置文件中,文件的名字默認爲:compass.cfg.xml,如果取名不一樣這在初始化 CompassConfiguration時,使用CompassConfiguration.config(fileName)。

因爲索引是事務性的。所以在進行操作的過程中,就存在鎖的概念。可以設置鎖文件的位置,默認爲java.io.tmp,<transaction lockDir="/shared/index-lock" />

別名、資源和屬性的概念:
資源(Resource):資源表示屬性的集合,相當於虛擬文檔。一個資源通常和一個別名聯繫在一起,幾個資源可以屬於同一個別名。別名擔當資源和映射定義的聯繫角色。屬性是指一個鍵值對。

在OSEM/XSEM中,容易忽視的是資源在何處被使用,因爲處理內容都被轉換成應用程序的模型或者是xml的結構數據。資源很少被使用。

通過資源和屬性,可以採用統一的方式訪問相同語義的模型。比如應用程序中有兩個模型:學生和教師。我們將學生和教師的名字都設置成相同語義的元數據:name(資源屬性名),這樣將會允許我們所有的name搜索顯示結果在資源層次上。

分析器:該組件主要是預處理輸入文本。用於搜索和索引的文本分析上。要求搜索和索引使用相同的分析器。
Compass內置兩個分析器名稱:default和search。缺省分析器用戶沒有其它分析器配置時使用。search用於搜索查詢的分析。
配置定製的分析器的參數可以通過Setting方式置入:
<analyzer name="deault" type="CustomAnalyzer" analyzerClass="eg.MyAnalyzer">
<setting name="threshold">5</setting>
</analyzer>


分析過濾器:
分析過濾器能夠被不同的分析器穿插使用。配置如下:
<analyzer name="deafult" type="Standard" filters="test1, test2" />
<analyzerFilter name="test1" type="eg.AnalyzerTokenFilterProvider1">
<setting name="param1" value="value1" />
</analyzerFilter>
<analyzerFilter name="test2" type="eg.AnalyzerTokenFilterProvider2">
<setting name="paramX" value="valueY" />
</analyzerFilter>

同義處理:同義處理分析過濾器:返回給定詞的同義詞
<analyzer name="deafult" type="Standard" filters="synonymFilter" />
<analyzerFilter name="synonymFilter" type="synonym">
<setting name="lookup" value="eg.MySynonymLookupProvider" />
</analyzerFilter>

查詢分析器:
<queryParser name="test" type="eg.MyQueryParser">
<setting name="param1" value="value1" />
</queryParser>



索引文件的結構:

compass的子索引相當於lucene的一個索引。當compound設置爲true時,lucene次採用一個segments文件存儲所有索引內容。子索引對事務型操作尤爲重要。

compass支持read_committed和serializable、batch_insert級別的事務

compass事務鎖用在自索引級別上,這意味着髒操作只發生在各自的子索引上。

compass事務在髒操作(創建,保存,刪除)時要求一個鎖。搜索時應該只用read only事務。鎖超時一般設置爲10秒。
<transaction lockTimeout="15" lockPollInterval="200" />


事務隔離:
1:read_committed:當開始該事務時,是不需要鎖的。因此速度會快。
2:serializable:和上面一樣。只是當事務開始時,對所有的自索引有一個鎖。性能降低。
3:batch_insert:使用了lucene提供的快速的批量索引的功能。這個事務操作只支持create操作。如果已經有同名的別名和ids的資源已經存在,那麼將會在一個索引中出現兩個資源。這種事務是不能回滾的。

FS Transaction Log:存儲許多事務數據到文件系統中。
<transaction isolation="read_committed">
<readCommittedSettings>
<fsTransLog path="/tmp" readBufferSize="32" writeBufferSize="4098" />
</readCommittedSettings>
</transaction>

常量子索引hash:
影射別名到子索引的最簡單辦法是將某個別名的所有的可搜索內容索引到相同的子索引裏面。如:
<compass-core-mapping>
<[mapping] alias="test-alias" sub-index="test-subindex">
<!-- ... -->
</[mapping]>
</compass-core-mapping>
test-alias將會影射所有的實例到test-subindex子索引中。如果sub-index沒有定義,則將缺省爲alias。

Modulo Sub Index Hashing:允許將一個別名代表的實例索引到不同的子索引中。根據給定的大小對索引進行分割。文件名是給定的前綴+“_"+數字。
<compass-core-mapping>
<[mapping] alias="A">
<sub-index-hash type="org.compass.core.engine.subindex.ModuloSubIndexHash">
<setting name="prefix" value="test" />
<setting name="size" value="2" />
</sub-index-hash>
<!-- ... -->
</[mapping]>
</compass-core-mapping>
會產生[test_0]和[test_1]兩個子索引文件。

Custom Sub Index Hashing:
ConstantSubIndexHash 和 ModuloSubIndexHash都實現了compass的SubIndexHash接口。定製子索引hash必須實現getSubIndexes和 mapSubIndex(String alias,Property[] ids)兩個方法。

Optimizers:優化器,每個髒操作提交成功都會在各自的子索引中產生另一個segment,子索引中的segment越多,搜索操作就越慢,因此保持索引優化,控制segment的數量很重要。要做的就是合併小segment到大的segment 。
索引優化器在子索引級別執行。在優化的過程中,優化器將鎖定子索引,以便於髒操作。

調度優化:compass的每一個優化器都能包裝爲調度方式執行。
<optimizer scheduleInterval="90" schedule="true" />

Aggressive Optimizer:通過設置segments的大小,當達到指定的大小時,將所有的segement合併到一個segment。這樣搜索的效率最高。
Adaptive Optimizer:和Aggressive Optimizer不同的是,該優化器只合並新的小segment。
Null Optimizer:不做任何優化。當做batch_insert事務時,離線創建索引或已經全部優化索引,一般使用它。

直接訪問Lucene:compass提供了LuceneHelper類,該類可以直接訪問lucene的api。

索引的對象遵循以下原則:
實現默認的無參數構造器,不要是public的。便於compass採用Constants.newInstance()
提供identifier,
提供訪問和設置方法
建議重載equals和hashcode方法。建議以業務主鍵爲參考。

alias:每一個影射定義都註冊了一個別名。這個別名用來聯繫類的osem定義和類本身。
Root:在compass中有兩類可搜索的類:root searchable和non-root searchable 類。root searchable類最好定義作爲hits結果返回的類。non-root searchable類不要求定義id影射。

子索引:默認情況下,每一個root searchable類都有自己的子索引,名稱缺省爲alias。子索引的名稱也可以自由控制。允許幾個root searchable類索引到相同的子索引中。或者用子索引hash功能。

searchable id不要求定義搜索的元數據,如果沒有定義,compass自動創建內部的元數據id。如果searchable id不需要被搜索,那麼需要爲它定義一個可搜索元數據。注意下面的元數據定義方式:

@Searchable
public class Author {
@SearchableId(name = "id")
private Long id;
// ...
}

@Searchable
public class Author {
@SearchableId
@SearchableMetaData(name = "id")
private Long id;
//

Searchable Constant:允許對一個類定義一系列的的常量數據。對於添加靜態元數據是非常有用的。
<constant>
<meta-data>type</meta-data>
<meta-data-value>person</meta-data-value>
<meta-data-value>author</meta-data-value>
</constant>

Searchable Dynamic Meta Data:允許將表達式的結果保存到搜索引擎中。該影射不能影射任何類屬性。動態元數據的值是根據動態轉換器計算表達式得到的。compass內建了比如 el,jexl,velocity,ognl,groovy等轉換器。當定義表達式後。root 類被註冊爲data key下的值。
<dynamic-meta-data name="test" converter="jexl">
data.value + data.value2
</dynamic-meta-data>

Searchable Reference:映射root類和其它類之間的關係。在marshals的過程中,只marshal參考對象的id。但是在unmarshal過程中根據id裝載參考的對象。
compass在參考對象上不執行任何級聯操作,也不提供延遲加載。
<class name="A" alias="a">
<id name="id" />
OSEM - Object/Search Engine Mapping
Compass - Java Search Engine 40
<reference name="b" />
<!-- ... -->
</class>
<class name="B" alias="b">
<id name="id" />
<!-- ... -->
</class>

Searchable Component:嵌入一個可搜索類到本身的搜索類中。組件參考搜索類能夠設置爲 Root。爲Root的組件一般都是具有id屬性。比如人員和姓名組件(non-root),人員和帳戶(root)。
<class name="A" alias="a">
<id name="id" />
<component name="b" />
<!-- ... -->
</class>
<class name="B" alias="b" root="false">
<!-- ... -->
</class>

繼承處理:
<class name="A" alias="a">
<id name="id" />
<property name="aValue">
<meta-data>aValue</meta-data>
</property>
</class>
<class name="B" alias="b" extends="a">
<property name="bValue">
<meta-data>aValue</meta-data>
</property>
</class>

Root 類有自己的索引,而依賴Root類的非Root類不需要索引。
Class mapping能夠繼承其它class mapping(可以超過一個)。也能夠繼承contract mapping。

contract:相當於java語言中的接口。如果有幾個相同的類具有相似的屬性。就可以定義一個contract。然後在子類中extend該 contract。

通用元數據提供了將元數據名稱和別名定義從osem文件提取到外面的方式。當你的應用程序有大量的域模型時尤其有用。另外一個優勢就是添加額外的信息倒元數據中,不如描述。也能制定元數據定義的格式,這樣就不用在osem 文件中定義了 。
通過集中話元數據,其它工具也能更好地利用這些信息。
OSEM文件引用通用元數據的方式是採用${}.

query syntax:
jack :缺省的查詢域中包括jack字段。
jack london:缺省的查詢域中包括 jack 或 london, 或者2者都有。
+jack +london: 缺省的查詢域中必須包括jack和london。
name:jack:name字段中包括jack。
name:jack -city:london :name字段中包括jack但是city字段中不包括london。
name:"jack london" :name字段中包括jack london短語。
name:"jack london"~5 :name字段包括至少5次jack and london短語
jack* 包含以jack開頭的詞條。
jack~ 包括以jack結尾的詞條。
birthday:[1870/01/01 TO 1920/01/01] birthday從1870-01-01到1920-01-01。


CompassHits, CompassDetachedHits & CompassHitsOperations:
compassHits:所有的搜索結果都是通過該接口訪問。只能用在事務上下文中。如果脫離上下文,則需要detached。compassHits和 compassDetachedHits都共享相同的操作接口:compassHitsOperation。

getLength() or length() :得到搜索資源的長度
score(n) 第n個搜索資源的分值。
resource(n) 第n個搜索資源
data(n) 第n個對象實例。

CompassQuery and CompassQueryBuilder:
CompassQueryBuilder提供了程序創建compassQuery的功能。compassQuery能夠用來添加排序和執行查詢。
CompassHits hits = session.createQueryBuilder()
.queryString("+name:jack +familyName:london")
.setAnalyzer("an1") // use a different analyzer
.toQuery()
.addSort("familyName", CompassQuery.SortPropertyType.STRING)
.addSort("birthdate", CompassQuery.SortPropertyType.INT)
.hits();

CompassQueryBuilder queryBuilder = session.createQueryBuilder();
CompassHits hits = queryBuilder.bool()
.addMust( queryBuilder.term("name", "jack") )
.addMustNot( queryBuilder.term("familyName", "london") )
.toQuery()
.addSort("familyName", CompassQuery.SortPropertyType.STRING)
.addSort("birthdate", CompassQuery.SortPropertyType.INT)
.hits();

注意排序的屬性必須是un_tokenized。

OSEM映射文件:
<class name="eg.A" alias="a">
<id name="id" />
<property name="familyName">
<meta-data>family-name</meta-data>
</property>
<property name="date">
<meta-data converter-param="YYYYMMDD">date-sem</meta-data>
</property>
Working with objects
Compass - Java Search Engine 78
</class>
查詢方式:採用compassQueryBuilder,許多查詢可以直接工作在mapping的層次上。
CompassQueryBuilder queryBuilder = session.createQueryBuilder();
CompassHits hits = queryBuilder.term("a.familyName.family-name", "london").hits();
// 採用類屬性的元數據id, 在上面的例子中將採用第一個元數據.
CompassHits hits = queryBuilder.term("a.familyName", "london").hits();
//查詢編輯器將會採用相應的轉化器轉換數據。
CompassHits hits = queryBuilder.term("a.date.date-sem", new Date()).hits();
CompassHits hits = queryBuilder.bool()
.addMust( queryBuilder.alias("a") )
.addMust( queryBuilder.term("a.familyName", "london") )
.toQuery().hits();

CompassHighlighter:提供高亮度匹配搜索的文字字段。
CompassHits hits = session.find("london");
String fragment = hits.highlighter(0).fragment("description");
高亮度只能用於CompassHits,只能用在事務上下文中。

在detachedHits中使用高亮度:
CompassHits hits = session.find("london");
//在事務上下文中處理高亮度。
for (int i = 0.; i < 10; i++) {
hits.highlighter(i).fragment("description"); // this will cache the highlighted fragment
}
CompassHit[] detachedHits = hits.detach(0, 10).getHits();
// outside of a transaction (maybe in a view technology)
for (int i = 0; i < detachedHits.length; i++) {
// this will return the first fragment
detachedHits[i].getHighlightedText().getHighlightedText();
// this will return the description fragment, note that the implementation
// implements the Map interface, which allows it to be used simply in JSTL env and others
detachedHits[i].getHighlightedText().getHighlightedText("description");
}

GPS通過2個概念提供了整合不同的可索引的數據源:CompassGps和CompassGpsDevice。Device可以結合任何類型的可索引數據來源,它提供索引數據、搜索數據、敏感數據變化的能力。 GPS建立在Compass基礎之上。利用Compass的特徵,如:事務、OSEM以及 API等。

CompassGps是GPS的主要接口,它擁有一系列的CompassGpsDevices,並且管理他們的生命週期。

Compass提供了兩個Gps的實現:
SingleCompassGps:擁有一個compass實例。這個compass實例用來做索引和鏡像操作。
DualCompassGps:擁有兩個Compass實例。indexCompass和mirrorCompass。主要處理兩個事務級別。 indexCompass一般採用 batch_insert隔離級別,而mirrorCompass採用read_committed事務級別。

hibernate Gps Device

hb3新的基於時間的機制提供了實時數據改變的鏡像。數據的傳送順序爲:Database -- Hibernate -- Objects -- Compass::Gps --Compass::Core (Search Engine).
在hb3中,程序配置:
Compass compass = ... // set compass instance
CompassGps gps = new SingleCompassGps(compass);
CompassGpsDevice hibernateDevice =
new Hibernate3GpsDevice("hibernate", sessionFactory);
gps.addDevice(hibernateDevice);
.... // configure other devices
gps.start();

hibernate device提供了一個fetchCount參數,這個參數控制索引一個類的分頁進程。

實時數據鏡像:在hb3中是基於新的時間機制。數據改變將會反射給compass index。配置時要注意的是系統和compass必須使用相同的SessionFactory。如果使用hb3和spring,請使用 SpringHibernate3GpsDevice。

Compass與spring結合:
1:支持compass級別的工廠bean。採用Spring ioc的配置選項。
2:提供Compass DAO級別的支持。採用事務整合和DAO支持類。
3:擴展GPS Hiberante3 device。
4:提供OJB的整合支持。
5:提供Spring MVC的搜索控制器和索引控制器。

spring中配置compass bean:
<bean id="compass"
class="org.compass.spring.LocalCompassBean">
<property name="resourceLocations">
<list>
<value>classpath:org/compass/spring/test/A.cpm.xml</value>
</list>
</property>
<property name="compassSettings">
<props>
<prop key="compass.engine.connection">
target/testindex
</prop>
<!-- This is the default transaction handling
(just explicitly setting it) -->
<prop key="compass.transaction.factory">
org.compass.core.transaction.LocalTransactionFactory
</prop>
</props>
</property>
</bean>

compass提供CompassDaoSupport類來執行Dao操作。

public class LibraryCompassDao extends CompassDaoSupport {
public int getNumberOfHits(final String query) {
Integer numberOfHits = (Integer)getCompassTemplate().execute(
new CompassCallback() {
public Object doInCompass(CompassSession session) {
CompassHits hits = session.find(query);
return new Integer(hits.getLength());
}
}
);
}
return numberOfHits.intValue();
}

然後配置該DAO類使用的Compass實例:
<beans>
<bean id="libraryCompass" class="LibraryCompassDao">
<property name="compass">
<ref local="compass" />
</property>
</bean>
</beans>

SpringSyncTransaction:compass將同步spring本身的事務.
SpringHibernate3GpsDevice:對Hibernate3GpsDevice的擴展,能夠處理spring帶來的 sessionFactory以便使用時間機制監聽實時數據改變。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章