百度首页 | 百度空间
 
查看文章
 
使用领域模型(domain object)来进行索引、搜索
2007/05/16 14:45

对于讲domain object 映射到关系型数据库中,hibernate等持久性框架做了很多的工作,使得业务逻辑只需要和hibernate等持久层进行交互,而不需要直接和具体的数据库进行交互。
这给程序员带来了很大的方便,在业务逻辑处理上,只要针对domain object就可以。
使用Lucene进行索引、搜索开发的的时候,最经常碰到的概念就是Document 和Field,在程序中一个不得不去做的事情,就是将领域对象的属性映射到document的field中去,在搜索的时候,还要根据document和field来构建DTOs(Data transfor object)来返回给web层。这点和EJB的一个缺点很类似,返回给web层的不能是实体Bean,而是对实体Bean进行封装了的DTO。
我们希望的是有类似POJO的技术带来的便利一样,持久化的是domain object,返回给web层的也是也是domain object。
我们在对domain object进行索引和搜索的时候,也希望能够直接在domain object的层面进行操作,而不是直接去和document和field打交道。而我们利用compass框架就可以做到这样。

Compass是使用了Lucene的搜索引擎框架,它提供了一套开源的、高性能的、可以灵活配置的搜索框架,可以为用户的应用程序提供搜索功能。它还能与Spring、Hibernate等已有的框架进行整合。

Comapss的API结构和hibernate非常的相似,如果使用过hibernate的程序员使用comapass,基本上对API就很得心应手。
我们来看一个例子
CompassConfiguration config = new CompassConfiguration().configure();
Compass compass = config.buildComapss();
CompassSession session = compass.openSession();
CompassTransaction tx = null;
try
{
    tx = session.beginTransaction();
    Book book = new Book();
    book.setName("C++编程思想");
    book.setAuthor(”Bruce Eckel“);
    session.save(book);
    tx.commit();
}catch(Exception e)
{
    if(tx!=null)
    {
       tx.rollback();
    }
}finally
{
    session.close();
}

Hiberanete的程序员对上面的代码应该是非常的熟悉吧,compass完全让你远离了Lucene的API,让你的代码更专注与业务逻辑,而把索引和搜索的事情都交给compass吧。这点还带来了一个优点,就是利用compass很容易的给已有的系统增加搜索的功能。

那么如何让domain object被compass使用呢,当然和hibernate一样,只要完成一些domai object的配置文件就可以了,具体的可以阅读compass附带的example

索引是简单了,那么搜索呢??
CompassSession session = compass.openSession();
CompassTransaction tx = null;
try
{
    tx = session.beginTransaction();
    CompassHits hits = session.find("
Bruce Eckel");
   tx.commit();
    CompassHit hit = hits.hit(0);
    if(hit.getAlias().equals("book");
    Book book = (Book) hit.getDate();

}catch(Exception e)
{
    if(tx!=null)
    {
       tx.rollback();
    }
}finally
{
    session.close();
}

这样就完成了搜索,只要使用session的find(String)方法,CompassHits是对lucene中的Hits的一个封装。find方法默认会在所有字段中进行该关键字的查找,如果你希望有自己的方式来查找,compass也提供了Lucene语法的查找,eg:
session.find("keyword:key*");

如果你对这些事务处理的代码比较反感的话,compass也提供了Template and Callback
这样就不需要担心session和transaction的处理了。

CompassConfiguration conf = new CompassConfiguration().configure().addClass(Author.class);
Compass compass = conf.buildCompass();
CompassTemplate template = new CompassTemplate(compass);
template.save(author); // open a session, transaction, and closes both
Author a = (Author) template.execute(new CompassCallback() {
public Object doInCompass(CompassSession session) {
// all the actions here are within the same session
// and transaction
session.save(author);
CompassHits hits = session.find("london");
...
return session.load(id);
}
});



最后说的就是compass虽然很大的程度上借鉴了hibernate的一些设计思想,但是目前版本的compass还没有完成一些hibernate中比较有用的功能。
1、Compass不支持级联(Casscading)
因为同样是针对domain object的操作,支持级联(Cascading)是必须的,但是compass目前的版本是需要程序员对每个对象都来save的。
2、compass目前还不支持lazy loading
当用户搜索并得到一个对象的时候,所有和这个对象相关联的对象也会被同时加载到内存中。

呵呵,compass还有很多吸引人的地方,本文只是针对domain object编程来看待compass带来的便利。

类别:Lucene | 添加到搜藏 | 浏览() | 评论 (0)
 
最近读者:
 
网友评论:
发表评论:
姓 名:
网址或邮箱: (选填)
内 容:
验证码:
 

     

©2008 Baidu