Compass读文档笔记

来源:百度文库 编辑:神马文学网 时间:2024/04/27 15:34:06
Compass是基于Lucene的更高层的抽象,假如你正打算做关于搜索方面的模块的话,那我建议你使用Compass,他提供了可配置方案,而且比Lucene更加容易使用。如果你的系统中使用Spring, Hibernate,JDO, IBatis。。。 Compass是最好的选择,他能够非常方便的集成到现有系统中去。
1.   Compass的framework的系统结构。
感觉Compass的代码的结构简直就是剽窃Hibernate的,可能Compass的最初目的是用来整合Hibernate的,
CompassConfiguration conf =
new CompassConfiguration().configure().addClass(Author.class);
Compass compass = conf.buildCompass();
CompassSession session = compass.openSession();
CompassTransaction tx = null;
try {
tx = session.beginTransaction();
...
session.save(author);
CompassHits hits = session.find("jack london");
Author a = (Author) hits.data(0);
Resource r = hits.getResource(0);
...
tx.commit();
} catch (CompassException ce) {
if (tx != null) tx.rollback();
} finally {
session.close();
}
假如你对Hibernate有了解的话,相信你对Compass会比较容易理解的,你可以把Hibernate的思想转移到Compass上。现在让我们看看他们之间的相似吧。
compass.cfg.xml
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.opensymphony.com/compass/schema/core-config
http://www.opensymphony.com/compass/schema/compass-core-config.xsd">









这个是Compass总的配置文件,其中定义了索引文件存储的位置(这里是用文件系统,Compass有多种选择,你也可以选数据库或其他),Compass索引的对象是面向PoJo的,这里的是Author,对应的文件是test/Author.cpm.xml.
当然这里面的配置属性不止这么多,更多的属性见Configure属性。
CompassConfiguration conf = new CompassConfiguration()
.setSetting(CompassEnvironment.CONNECTION, "my/index/dir")
.addResource(DublinCore.cmd.xml).addClass(Author.class);
Compass compass = conf.buildCompass();
这里我们CompassConfiguration会读取默认的在classpath中的compass.cfg.xml初始化,然后得到Compass对象,可能你会马上意思到这个Compass肯定对应于Hibenate中的SessionFactory,是的,这是一个重量级的对象,
我们需要通过这个对象得到CompassSession,然后进行CRUD操作,CompassSession跟Hibernate中的Session一样是个lightweight对象。关于对Search domain的配置(Author.cpm.xml),大家可以查看cpm文件配置。在那里面
主要是定义了那些properties是需要被索引的。





type
person
author


name
authorName


birthday





...


2.  索引文件结构
---[index dir]/index
|
|-- [subIndex1]
|      |
|      |--- segments
|      |--- [segment1]
|      |--- [segment2]
|
|-- [subIndex2]
|      |
|      |--- segments
|      |--- [segment1]
|      |--- [segment2]
|      |--- [segment3]
|
...
基本上是一个search domain放到一个subIndex文件夹中,更确切的说是相同alias name的search domain放到相同的sub index folder中。
3.  Compass中的操作
通过CompassSession我们可以进行save,delete, get,load。假如我们有两个domain Object,Author和 Book,假如我们想要query Book的话要怎样做呢? 我们需要使用alias(这个属性定义在cmp文件中),
通过CompassQueryBuilder去构造CompassQuery, CompassQueryBuilder非常灵活,非常像Hibernate的Criteria查询。具体的sample请看 Working with objects
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();
4.  CompassGps and CompassGpsDevice
CompassGps像是一个Service,他需要在application startup时启动服务, applicationshutdown停止服务,CompassGpsDevice不能独立的存在,他需要依赖CompassGps,CompassGps为CompassGpsDevice提供
Compass对象,他们一起为程序提供Index的实时更新。Compass整合Hibernate 等等 persitanceframework的代码就在CompassGpsDevice里,你需要提供不同的Device,如HibernateDevice,JDODevice。你也
可以实现自己的Device, CompassGpsDevice会把domain object的更新事件通过CompassGps去通知Compass去更新索引文件,这样就是可以实时更新index了。有兴趣的话可以看看Hibernate3GpsDevice的
registerEventsForHibernate31()方法,他给Hibernate的save,delete,update操作增加listener。当然我们可以使用aop自己去实现这块。CompassGps and CompassGpsDevice
Compass compass = ... // configure compass
CompassGps gps = new SingleCompassGps(compass);
CompassGpsDevice device1 = ... // configure the first device
device1.setName("device1");
gps.addDevice(device1);
CompassGpsDevice device2 = ... // configure the second device
device2.setName("device2");
gps.addDevice(device2);
gps.start();
....
....
//on application shutdown
gps.stop();
5.  整合Spring,Hibenate
在Compass的lib里面就有非常好的一个sample了(petclinic),里面有对Spring,Hibenate的整合,其实对spring来说也就是通过ioc把CompassGps 和 Compass定义好。CompassGps主要负责re-index和index实时更新
,Compass主要提供了自定义Search部分的入口(CompassTemplate)。Spring提供了对Compass的DAO的整合,在CompassDaoSupport 中拿到CompassTemplate,这个跟spring对hibernatedao的支持是一致的。
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();
}











classpath:org/compass/sample/petclinic/petclinic.cmd.xml
classpath:petclinic.cpm.xml




file://${user.home}/compass/petclinic
org.compass.spring.transaction.SpringSyncTransactionFactory







hibernateDevice
















class="org.compass.annotations.config.CompassAnnotationsConfiguration">






com.dengyin.compass.sample.domain.Book







file://${user.home}/springside/compass


org.compass.spring.transaction.SpringSyncTransactionFactory






init-method="start" destroy-method="stop">





hibernateDevice






ok! 相信你对Compass有一定的了解了。 thanks
Compass:    http://www.opensymphony.com/compass/
Compass文档:http://www.opensymphony.com/compass/content/documentation.html