`
HelloTommy
  • 浏览: 96955 次
  • 性别: Icon_minigender_1
  • 来自: 慈溪
社区版块
存档分类
最新评论

Compass的一个简单例子

阅读更多

Compass的一个简单例子

Compass是一个封装了Lucene的框架。使用Compass的API可以非常方便地建立索引、删除索引、实现检索。Compass非常像Hibernate,Compass封装了Lucene就像Hibernate封装了JDBC操作一样,通过简单的API就能实现底层的操作。

但是,初次接触Compass,并不像想象的那样,我想,在以后的不断学习中,会一点点地深入理解Compass的更多内容。

感觉,如果不真正地实现一个Compass的例子,即使是非常简单的例子,我的印象中的Compass还是很模糊的。就拿一个最简单的例子来展示一下Compass到底能够做到什么,有了这样一种直观的印象,才能与Compass拉近距离,便于深入学习。

新建一个Java Project,作为测试的工程。

Compass版本

Compass 1.2

工程结构

实现Compass的例子的工程结构如下所示:

Compass
│ .classpath
│ .project

├─bin
│ └─org
│      └─shirdrn
│          └─compass
│              │ compass.cfg.xml
│              │
│              ├─document
│              │      alias.cmd.xml
│              │      Book.class
│              │      Book.cpm.xml
│              │
│              └─main
│                      MyCompass.class

├─src
│ └─org
│      └─shirdrn
│          └─compass
│              │ compass.cfg.xml
│              │
│              ├─document
│              │      alias.cmd.xml
│              │      Book.cpm.xml
│              │      Book.java
│              │
│              └─main
│                      MyCompass.java

└─target
    └─index
        └─index
            └─book
                    segments.gen
                    segments_5
                    _0.cfs
                    _0_1.del
                    _1.cfs
                    _1_1.del
                    _2.cfs
                    _3.cfs

上面的红色部分(即target所在目录分支)是在运行程序的时候才生成的,在目录/target/index/index/book/下面生成的就是索引文件。这些文件的格式,在Lucene中已经非常熟悉了。

开发过程

需要用到的jar包,通过工程的classpath文件可以看到都用到了哪些jar包,如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="lib" path="E:/JAR包/Compass 1.2/compass.jar"/>
<classpathentry kind="lib" path="E:/JAR包/Others/log4j-1.2.11.jar"/>
<classpathentry kind="lib" path="E:/Compass/compass-1.2-with-dependencies/compass-1.2/lib/lucene/lucene-core.jar"/>
<classpathentry kind="lib" path="E:/Compass/compass-1.2-with-dependencies/compass-1.2/lib/lucene/lucene-highlighter.jar"/>
<classpathentry kind="lib" path="E:/Compass/compass-1.2-with-dependencies/compass-1.2/lib/lucene/lucene-queries.jar"/>
<classpathentry kind="lib" path="E:/Compass/compass-1.2-with-dependencies/compass-1.2/lib/lucene/lucene-snowball.jar"/>
<classpathentry kind="lib" path="E:/Compass/compass-1.2-with-dependencies/compass-1.2/lib/lucene/lucene-analyzers.jar"/>
<classpathentry kind="lib" path="E:/Compass/compass-1.2-with-dependencies/compass-1.2/lib/log4j/log4j-1.2.13.jar"/>
<classpathentry kind="lib" path="E:/Compass/compass-1.2-with-dependencies/compass-1.2/dist/commons-logging.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>

看看Compass的配置文件compass.cfg.xml是如何配置的:

<!DOCTYPE compass-core-configuration PUBLIC
    "-//Compass/Compass Core Configuration DTD 1.0//EN"
    "http://www.opensymphony.com/compass/dtd/compass-core-configuration.dtd">
<compass-core-configuration>
<compass>
   <setting name="compass.engine.connection">target/index</setting>
   <meta-data
    resource="org/shirdrn/compass/document/alias.cmd.xml" />
</compass>
</compass-core-configuration>

很像Hibernate的配置文件。

setting元素中配置了索引文件的存放位置,上面为target/index,即在当前工程目录下,生成的索引文件会存放在target/index/index/目录下。

meta-data元素通过指定属性resource的值,即一个包含完整包名的alias(别名)定义文件。alias.cmd.xml文件中包含的内容是一个实体类的相关信息,如下所示:

<?xml version="1.0"?>
<!DOCTYPE compass-core-meta-data PUBLIC
    "-//Compass/Compass Core Meta Data DTD 1.0//EN"
    "http://www.opensymphony.com/compass/dtd/compass-core-meta-data.dtd">
<compass-core-meta-data>
<meta-data-group id="mybooks" displayName="Mybooks Meta Data">

   <description>Book Meta Data</description>
   <uri>http://compass/mybooks</uri>

   <alias id="book" displayName="Book">
    <description>Book alias</description>
    <uri>http://compass/mybooks/Book</uri>
    <name>book</name>
   </alias>
   <meta-data id="bookNo" displayName="BookNo">
    <description>Author alias</description>
    <uri>http://compass/mybooks/bookNo</uri>
    <name>bookNo</name>
   </meta-data>
   <meta-data id="bookName" displayName="BookName">
    <description>BookName alias</description>
    <uri>http://compass/mybooks/bookName</uri>
    <name>bookName</name>
   </meta-data>
   <meta-data id="author" displayName="Author">
    <description>Text alias</description>
    <uri>http://compass/mybooks/author</uri>
    <name>author</name>
   </meta-data>
   <meta-data id="category" displayName="Category">
    <description>Category alias</description>
    <uri>http://compass/mybooks/category</uri>
    <name>category</name>
   </meta-data>
   <meta-data id="contents" displayName="Contents">
    <description>Text alias</description>
    <uri>http://compass/mybooks/contents</uri>
    <name>contents</name>
   </meta-data>
   <meta-data id="price" displayName="Price">
    <description>Price alias</description>
    <uri>http://compass/mybooks/price</uri>
    <name>price</name>
   </meta-data>
</meta-data-group>

</compass-core-meta-data>

该文件中meta-data-group元素的id属性值标识了一个组id,通过它可以设置一个实体类的每个属性的元数据(meta-data),在后面的实体(Book)的映射文件中可以看到。

在Compass中,实体类对应于Lucene中的Document,就像Hibernate中的POJO对应于数据库中的表一样,是这样的一种映射的关系。

为了测试,只建立一个实体类Book类,就是一个JavaBean,Book。Book.java的代码如下所示:

package org.shirdrn.compass.document;

public class Book {

private String bookNo;
private String bookName;
private String author;
private String category;
private String contents;
private Double price;

public String getAuthor() {
   return author;
}
public void setAuthor(String author) {
   this.author = author;
}
public String getCategory() {
   return category;
}
public void setCategory(String category) {
   this.category = category;
}
public String getContents() {
   return contents;
}
public void setContents(String contents) {
   this.contents = contents;
}

public Double getPrice() {
   return price;
}
public void setPrice(Double price) {
   this.price = price;
}
public String getBookNo() {
   return bookNo;
}
public void setBookNo(String bookNo) {
   this.bookNo = bookNo;
}
public String getBookName() {
   return bookName;
}
public void setBookName(String bookName) {
   this.bookName = bookName;
}

}

其中,在Book.java中定义了几个属性,这些属性对应于Lucene中的Field。

一个实体类对应着一个映射文件,比如Book类对应的映射文件名称为Book.cpm.xml,配置如下所示:

<?xml version="1.0"?>
<!DOCTYPE compass-core-mapping PUBLIC
    "-//Compass/Compass Core Mapping DTD 1.0//EN"
    "http://www.opensymphony.com/compass/dtd/compass-core-mapping.dtd">
<compass-core-mapping package="org.shirdrn.compass.document">
<class name="Book" alias="${mybooks.book}">
   <id name="bookNo" />
   <property name="bookName">
    <meta-data>${mybooks.bookName}</meta-data>
   </property>
   <property name="author">
    <meta-data>${mybooks.author}</meta-data>
   </property>
   <property name="category">
    <meta-data>${mybooks.category}</meta-data>
   </property>
   <property name="contents">
    <meta-data>${mybooks.contents}</meta-data>
   </property>
   <property name="price">
    <meta-data>${mybooks.price}</meta-data>
   </property>
</class>

</compass-core-mapping>

通过使用alias.cmd.xml文件中的meta-data-group id="mybooks"来设置一个实体的属性,使用${}来设置。

其中,id唯一地标识了一个Book对象,可以对其执行save、delete操作,其实就是在对一个Document进行上述操作。

编写一个测试类MyCompass类,如下所示:

package org.shirdrn.compass.main;

import org.compass.core.Compass;
import org.compass.core.CompassHits;
import org.compass.core.CompassSession;
import org.compass.core.CompassTransaction;
import org.compass.core.config.CompassConfiguration;
import org.shirdrn.compass.document.Book;

public class MyCompass {

private static Compass compass;
static{    // 解析Compass配置文件,加载Book实体类
   CompassConfiguration config = new CompassConfiguration();
   config.configure("/org/shirdrn/compass/compass.cfg.xml");
   config.addClass(Book.class);
   compass = config.buildCompass();
}

private Book addBookA(){ //   构造一个Book实例,实际上是构造了一个Document,并向其中添加Field
   Book book = new Book();
   book.setBookNo("ISBN 987-5-624-16000-8/TP");
   book.setBookName("Compass框架技术");
   book.setAuthor("飞云居士");
   book.setCategory("Java");
   String contents = "Compass是封装了Lucene的一个功能强大的框架。"+
       "Compass简单易学,这使得开发者可以像使用Hibernate一样轻松地开发自己的搜索引擎。"+
       "即使对Lucene并不是很熟悉,使用Compass框架开发使你变得游刃有余。";
   book.setContents(contents);
   book.setPrice(new Double(23.00));
   return book;
}

private Book addBookB(){
   Book book = new Book();
   book.setBookNo("ISBN 388-2-244-16000-9/TP");
   book.setBookName("鬼吹灯");
   book.setAuthor("本物天下霸唱");
   book.setCategory("考古小说类");
   String contents = "几位“摸金校尉”(盗墓贼)通过风水秘术在发掘古墓时的诡异经历。"+
       "主人公胡八一祖传的风水秘书残卷,上山下乡时误入大山深处的辽代古墓,"+
       "参军时在昆仑山大冰川发现的九层妖楼,东北中蒙边境的关东军秘密地下...";
   book.setContents(contents);
   book.setPrice(new Double(58.50));
   return book;
}

private void createIndex(Book book) {    // 建立索引,与Hibernate很相似
   CompassSession session = compass.openSession();
   CompassTransaction tx = session.beginTransaction();
   session.save(book);
   tx.commit();
   session.close();
}

private void search(String keyword) {    // 根据关键字keyword检索
   CompassSession session = compass.openSession();
   CompassTransaction tx = session.beginTransaction();
   CompassHits hits = session.find(keyword);
   System.out.println("检索关键字 "+keyword+" 的检索结果如下:");
   System.out.println("********************************************");
   for (int i = 0; i < hits.getLength(); i++) {
    Book book = (Book)hits.data(i);
    System.out.println("书的编号为: "+book.getBookNo());
    System.out.println("书的名称为: "+book.getBookName());
    System.out.println("书的作者为: "+book.getAuthor());
    System.out.println("书的类别为: "+book.getCategory());
    System.out.println("书的内容为: "+book.getContents());
    System.out.println("书的定价为: "+book.getPrice());
    System.out.println("********************************************");
   }
   System.out.println("共检索出结果 "+hits.length()+" 个。");
   hits.close();
   tx.commit();
   session.close();
   compass.close();
}

public static void main(String[] args) {
   MyCompass myCompass = new MyCompass();
   myCompass.createIndex(myCompass.addBookA());
   myCompass.createIndex(myCompass.addBookB());
   myCompass.search("鬼吹灯");
}
}

通过两个方法:addBookA()和addBookB()构造两个Book实例,要为它们建立索引。

当执行上面测试函数的时候,会在工程目录下生成如下索引目录:

\target\index\index\book\

在索引目录下生成建立的索引文件。

通过Book的bookName来检索,检索关键字“鬼吹灯”,运行结果如下所示:

检索关键字 鬼吹灯 的检索结果如下:
********************************************
书的编号为: ISBN 388-2-244-16000-9/TP
书的名称为: 鬼吹灯
书的作者为: 本物天下霸唱
书的类别为: 考古小说类
书的内容为: 几位“摸金校尉”(盗墓贼)通过风水秘术在发掘古墓时的诡异经历。主人公胡八一祖传的风水秘书残卷,上山下乡时误入大山深处的辽代古墓,参军时在昆仑山大冰川发现的九层妖楼,东北中蒙边境的关东军秘密地下...
书的定价为: 58.5
********************************************
共检索出结果 1 个。

如果想要通过文章中词条作为关键字来检索,也一样,比如检索关键字“的”,因为它在两个Book的内容中都出现了,预测应该能检索出两个Book。

看运行结果,如下所示:

检索关键字 的 的检索结果如下:
********************************************
书的编号为: ISBN 388-2-244-16000-9/TP
书的名称为: 鬼吹灯
书的作者为: 本物天下霸唱
书的类别为: 考古小说类
书的内容为: 几位“摸金校尉”(盗墓贼)通过风水秘术在发掘古墓时的诡异经历。主人公胡八一祖传的风水秘书残卷,上山下乡时误入大山深处的辽代古墓,参军时在昆仑山大冰川发现的九层妖楼,东北中蒙边境的关东军秘密地下...
书的定价为: 58.5
********************************************
书的编号为: ISBN 987-5-624-16000-8/TP
书的名称为: Compass框架技术
书的作者为: 飞云居士
书的类别为: Java
书的内容为: Compass是封装了Lucene的一个功能强大的框架。Compass简单易学,这使得开发者可以像使用Hibernate一样轻松地开发自己的搜索引擎。即使对Lucene并不是很熟悉,使用Compass框架开发使你变得游刃有余。
书的定价为: 23.0
********************************************
共检索出结果 2 个。

修改和删除索引,需要通过一个实体类对象的唯一标识来定位该索引文件,然后对其删除或者修改,比如上面的Book中bookNo就可以标识一个Book对象,通过指定一个bookNo,通过CompassSession的delete方法进行删除。

删除索引的操作也是非常简单的,如下所示:

private void deleteIndex(Book book) { // 删除索引,与Hibernate很相似
   CompassSession session = compass.openSession();
   CompassTransaction tx = session.beginTransaction();
   session.delete(book);
   tx.commit();
   session.close();
}

修改索引与Hibernate稍有不同,实际上是先把原来已经存在的索引删除掉,之后再重新创建索引,如下所示:

private void updateIndex(Book book) { // 修改索引
   CompassSession session = compass.openSession();
   CompassTransaction tx = session.beginTransaction();
   session.delete(book);
   session.save(book);
   tx.commit();
   session.close();
}

上面实现这个例子是最最基础的,供参考以入门。

 

为了您的安全,请只打开来源可靠的网址

打开网站    取消

来自: http://hi.baidu.com/shirdrn/blog/item/b733ce083bbc29900a7b8296.html
分享到:
评论
1 楼 effort_fan 2010-11-28  
最近正在学,很有用,学习了。谢谢分享。

相关推荐

    compass实例zip

    Compass是一个强大的,事务的,高性能的对象/搜索引擎映射(OSEM:object/search engine mapping)与一个Java持久层框架.Compass包括: * 搜索引擎抽象层(使用Lucene搜索引荐), * OSEM (Object/Search Engine Mapping) ...

    compass2简单例子

    博文链接:https://qsrock.iteye.com/blog/203962

    SSH2+compass2.2搜索实例(完整工程)

    Struts2.2.3+Spring 3.0.6 + Hibernate3.6+compass2.2的完整工程,用myeclipse导入工程,用mysql导入数据库即可(包含sql脚本及简单操作说明)

    java源码包---java 源码 大量 实例

     Tcp服务端与客户端的JAVA实例源代码,一个简单的Java TCP服务器端程序,别外还有一个客户端的程序,两者互相配合可以开发出超多的网络程序,这是最基础的部分。 递归遍历矩阵 1个目标文件,简单! 多人聊天室 3...

    JAVA上百实例源码以及开源项目源代码

     Tcp服务端与客户端的JAVA实例源代码,一个简单的Java TCP服务器端程序,别外还有一个客户端的程序,两者互相配合可以开发出超多的网络程序,这是最基础的部分。 递归遍历矩阵 1个目标文件,简单! 多人聊天室 3...

    sass-compass-cli:sass-compass-cli,快速构建scss项目

    构建Sass-compass项目的简单cli。 安装 先决条件:Node.js(&gt; = 6.x,首选8.x),npm版本3+ npm install -g sass-compass-cli 用法 sass-compass new 例子 sass-compass new my-sass-study 安装时,系统会要求您...

    JAVA上百实例源码以及开源项目

     Tcp服务端与客户端的JAVA实例源代码,一个简单的Java TCP服务器端程序,别外还有一个客户端的程序,两者互相配合可以开发出超多的网络程序,这是最基础的部分。 递归遍历矩阵 1个目标文件,简单! 多人聊天室 3...

    java源码包2

     Tcp服务端与客户端的JAVA实例源代码,一个简单的Java TCP服务器端程序,别外还有一个客户端的程序,两者互相配合可以开发出超多的网络程序,这是最基础的部分。 递归遍历矩阵 1个目标文件,简单! 多人聊天室 ...

    compass.js:用于绘制形状的 JavaScript 库

    指南针.js 用于绘制形状的简单 JavaScript 库。用法引用库: [removed][removed]例子使用单个指南针的简单模式: : 使用许多指南针的更复杂的模式: :

    java源码包3

     Tcp服务端与客户端的JAVA实例源代码,一个简单的Java TCP服务器端程序,别外还有一个客户端的程序,两者互相配合可以开发出超多的网络程序,这是最基础的部分。 递归遍历矩阵 1个目标文件,简单! 多人聊天室 ...

    java源码包4

     Tcp服务端与客户端的JAVA实例源代码,一个简单的Java TCP服务器端程序,别外还有一个客户端的程序,两者互相配合可以开发出超多的网络程序,这是最基础的部分。 递归遍历矩阵 1个目标文件,简单! 多人聊天室 ...

    成百上千个Java 源码DEMO 4(1-4是独立压缩包)

    Tcp服务端与客户端的JAVA实例源代码 2个目标文件 摘要:Java源码,文件操作,TCP,服务器 Tcp服务端与客户端的JAVA实例源代码,一个简单的Java TCP服务器端程序,别外还有一个客户端的程序,两者互相配合可以开发出超多...

    成百上千个Java 源码DEMO 3(1-4是独立压缩包)

    Tcp服务端与客户端的JAVA实例源代码 2个目标文件 摘要:Java源码,文件操作,TCP,服务器 Tcp服务端与客户端的JAVA实例源代码,一个简单的Java TCP服务器端程序,别外还有一个客户端的程序,两者互相配合可以开发出超多...

    java开源包1

    GWT Spring 使得在 Spring 框架下构造 GWT 应用变得很简单,提供一个易于理解的依赖注入和RPC机制。 Java扫雷游戏 JVMine JVMine用Applets开发的扫雷游戏,可在线玩。 public class JVMine extends java.applet....

    java开源包2

    GWT Spring 使得在 Spring 框架下构造 GWT 应用变得很简单,提供一个易于理解的依赖注入和RPC机制。 Java扫雷游戏 JVMine JVMine用Applets开发的扫雷游戏,可在线玩。 public class JVMine extends java.applet....

    java开源包3

    GWT Spring 使得在 Spring 框架下构造 GWT 应用变得很简单,提供一个易于理解的依赖注入和RPC机制。 Java扫雷游戏 JVMine JVMine用Applets开发的扫雷游戏,可在线玩。 public class JVMine extends java.applet....

    java开源包6

    GWT Spring 使得在 Spring 框架下构造 GWT 应用变得很简单,提供一个易于理解的依赖注入和RPC机制。 Java扫雷游戏 JVMine JVMine用Applets开发的扫雷游戏,可在线玩。 public class JVMine extends java.applet....

Global site tag (gtag.js) - Google Analytics