`
唐风汉月
  • 浏览: 51262 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

Compass全文检索系列之一:Compass入门

阅读更多
   Compass框架的参考文档,Compass是在Lucene的基础上做了封装,支持索引事务控制和增量索引,同时也能够和主流的SSH框架完美地整合在一起,操作Compass类似于操作Hibernate,它们的类/方法等设计的非常相似。下面我们通过一个实例来看看Compass到底是怎样来索引数据库,操作索引库和实现搜索功能的。
    步骤一:下载Compass,目前最新版本是2.2.0,可以到http://www.compass-project.org/上下载。
    步骤二:在Eclipse中新建一个Java Project,解压compass-2.2.0-with-dependencies.zip,将dist目录下的compass-2.2.0.jar,commons-logging.jar和dist/lucene目录下的lucene-analyzers.jar,lucene-core.jar,lucene-highlighter.jar拷贝在工程的构建路径下,如下图所示:

    步骤三:新建一个Book(书籍)类,这个类就是我们要搜索的对象,其完整代码如下:

import org.compass.annotations.Index;
import org.compass.annotations.Searchable;
import org.compass.annotations.SearchableId;
import org.compass.annotations.SearchableProperty;
import org.compass.annotations.Store;

@Searchable
public class Book {
	private String id;//编号
	private String title;//标题
	private String author;//作者
	private float price;//价格

	public Book() {
	}

	public Book(String id, String title, String author, float price) {
		super();
		this.id = id;
		this.title = title;
		this.author = author;
		this.price = price;
	}

	@SearchableId
	public String getId() {
		return id;
	}

	@SearchableProperty(boost = 2.0F, index = Index.TOKENIZED, store = Store.YES)
	public String getTitle() {
		return title;
	}

	@SearchableProperty(index = Index.TOKENIZED, store = Store.YES)
	public String getAuthor() {
		return author;
	}

	@SearchableProperty(index = Index.NO, store = Store.YES)
	public float getPrice() {
		return price;
	}

	public void setId(String id) {
		this.id = id;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public void setAuthor(String author) {
		this.author = author;
	}

	public void setPrice(float price) {
		this.price = price;
	}

	@Override
	public String toString() {
		return "[" + id + "] " + title + " - " + author + " $ " + price;
	}

}

    这里有几个要注意的地方:@Searchable表示该类的对象是可被搜索的;@SearchableId表示索引建立的id;@SearchableProperty表示此字段可以被索引、被检索;对于Index,Store在这里就不作介绍了,不熟悉的朋友可以去看看Lucene API。
    步骤四:新建一个Searcher类,该类封装了对索引库的一些操作,包括新建索引,删除索引,重建索引,搜索等等。完整代码如下:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.compass.annotations.config.CompassAnnotationsConfiguration;
import org.compass.core.Compass;
import org.compass.core.CompassHits;
import org.compass.core.CompassSession;
import org.compass.core.CompassTransaction;

public class Searcher
{
	protected Compass compass;

	public Searcher()
	{
	}

	/**
	 * 初始化Compass
	 * @param path
	 */
	public Searcher(String path)
	{
		compass = new CompassAnnotationsConfiguration().setConnection(path).addClass(Book.class).setSetting("compass.engine.highlighter.default.formatter.simple.pre", "<font color='red'>").setSetting(
				"compass.engine.highlighter.default.formatter.simple.post", "</font>").buildCompass();
		Runtime.getRuntime().addShutdownHook(new Thread()
		{
			public void run()
			{
				compass.close();
			}
		});

	}

	/**
	 * 新建索引
	 * @param book
	 */
	public void index(Book book)
	{
		CompassSession session = null;
		CompassTransaction tx = null;
		try
		{
			session = compass.openSession();
			tx = session.beginTransaction();
			session.create(book);
			tx.commit();
		} catch (RuntimeException e)
		{
			if(tx!=null)
				tx.rollback();
			throw e;
		} finally
		{
			if (session != null)
			{
				session.close();
			}
		}
	}

	/**
	 * 删除索引
	 * @param book
	 */
	public void unIndex(Book book)
	{
		CompassSession session = null;
		CompassTransaction tx = null;
		try
		{
			session = compass.openSession();
			tx = session.beginTransaction();
			session.delete(book);
			tx.commit();
		} catch (RuntimeException e)
		{
			tx.rollback();
			throw e;
		} finally
		{
			if (session != null)
			{
				session.close();
			}
		}
	}

	/**
	 * 重建索引
	 * @param book
	 */
	public void reIndex(Book book)
	{
		unIndex(book);
		index(book);
	}

	/**
	 * 搜索
	 * @param queryString
	 * @return
	 */
	public List<Book> search(String queryString)
	{
		CompassSession session = null;
		CompassTransaction tx = null;
		try
		{
			session = compass.openSession();
			tx = session.beginTransaction();
			CompassHits hits = session.find(queryString);
			int n = hits.length();
			if (0 == n)
			{
				return Collections.emptyList();
			}
			List<Book> books = new ArrayList<Book>();
			for (int i = 0; i < n; i++)
			{
				books.add((Book) hits.data(i));
			}
			hits.close();
			tx.commit();
			return books;
		} catch (RuntimeException e)
		{
			tx.rollback();
			throw e;
		} finally
		{
			if (session != null)
			{
				session.close();
			}
		}
	}
}

    步骤五:新建一个测试类进行测试.完整源码如下:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

public class Main
{
	static List<Book> db = new ArrayList<Book>();
	static Searcher searcher = new Searcher("E:/index");

	public static void main(String[] args)
	{
		add(new Book(UUID.randomUUID().toString(), "Thinking in Java", "Bruce", 109.0f));
		add(new Book(UUID.randomUUID().toString(), "Effective Java", "Joshua", 12.4f));
		add(new Book(UUID.randomUUID().toString(), "Java Thread Programing", "Paul", 25.8f));
		int n;
		do
		{
			n = displaySelection();
			switch (n)
			{
			case 1:
				listBooks();
				break;
			case 2:
				addBook();
				break;
			case 3:
				deleteBook();
				break;
			case 4:
				searchBook();
				break;
			case 5:
				return;
			}
		} while (n != 0);
	}

	static int displaySelection()
	{
		System.out.println("\n==select==");
		System.out.println("1. List all books");
		System.out.println("2. Add book");
		System.out.println("3. Delete book");
		System.out.println("4. Search book");
		System.out.println("5. Exit");
		int n = readKey();
		if (n >= 1 && n <= 5)
			return n;
		return 0;
	}

	/**
	 * 增加一本书到数据库和索引中
	 * @param book
	 */
	private static void add(Book book)
	{
		db.add(book);
		searcher.index(book);
	}

	/**
	 * 打印出数据库中的所有书籍列表
	 */
	public static void listBooks()
	{
		System.out.println("==Database==");
		int n =1;
		for (Book book :db)
		{
			System.out.println(n+")"+book);
			n++;
		}
	}

	/**
	 * 根据用户录入,增加一本书到数据库和索引中
	 */
	public static void addBook()
	{
		String title = readLine(" Title: ");
		String author = readLine(" Author: ");
		String price = readLine(" Price: ");
		Book book = new Book(UUID.randomUUID().toString(),title,author,Float.valueOf(price));
		add(book);
	}

	/**
	 * 删除一本书,同时删除数据库,索引库中的
	 */
	public static void deleteBook()
	{
		listBooks();
		System.out.println("Book index: ");
		int n = readKey();
		Book book = db.remove(n-1);
		searcher.unIndex(book);
	}

	/**
	 * 根据输入的关键字搜索书籍
	 */
	public static void searchBook()
	{
		String queryString = readLine(" Enter keyword: ");
		List<Book> books = searcher.search(queryString);
		System.out.println(" ====search results:"+books.size()+"====");
		for (Book book :books)
		{
			System.out.println(book);
		}
	}

	public static int readKey()
	{
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
		try
		{
			int n = reader.read();
			n=Integer.parseInt(Character.toString((char)n));
			return n;
		}catch(Exception e)
		{
			throw new RuntimeException();
		}
	}
	
	public static String readLine(String propt)
	{
		System.out.println(propt);
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
		try{
			return reader.readLine();
		}catch(Exception e)
		{
			throw new RuntimeException();
		}
	}
}


    该工程整个文件结构如下图所示:



    运行结果:




    项目源码:如下

  • 大小: 5.1 KB
  • 大小: 6.8 KB
  • 大小: 13.4 KB
  • 大小: 11.4 KB
分享到:
评论
3 楼 sjxinrui 2012-05-14  
挺好,=-=   加油
2 楼 aa00aa00 2012-03-27  
这个例子不错,谢谢了
1 楼 oolala 2010-11-21  
不错,不错。坚持写呀。

相关推荐

    compass全文检索

    网站快速加入全文检索文档,介绍compass基础知识入门、准备、开发入门等

    自己动手写搜索引擎

    该书详细讲解了搜索引擎与信息检索基础,Lucene入门实例,Lucene索引的建立,使用Lucene进行搜索,排序,过滤和分页,Lucene的分析器,对Word、Excel和PDF格式文档的处理,Compass搜索引擎框架,Lucene分布式和...

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

    5个目标文件,演示Address EJB的实现,创建一个EJB测试客户端,得到名字上下文,查询jndi名,通过强制转型得到Home接口,getInitialContext()函数返回一个经过初始化的上下文,用client的getHome()函数调用Home接口...

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

    Message-Driven Bean EJB实例源代码 2个目标文件 摘要:Java源码,初学实例,EJB实例 Message-Driven Bean EJB实例源代码,演示一个接收购物订单的消息驱动Bean,处理这个订单同时通过e-mail的形式 //给客户发一个感谢...

    java开源包1

    GiftedMotion是一个很小的,免费而且易于使用图像互换格式动画是能够设计一个有趣的动画了一系列的数字图像。使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的...

    java开源包11

    GiftedMotion是一个很小的,免费而且易于使用图像互换格式动画是能够设计一个有趣的动画了一系列的数字图像。使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的...

    java开源包2

    GiftedMotion是一个很小的,免费而且易于使用图像互换格式动画是能够设计一个有趣的动画了一系列的数字图像。使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的...

    java开源包3

    GiftedMotion是一个很小的,免费而且易于使用图像互换格式动画是能够设计一个有趣的动画了一系列的数字图像。使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的...

    java开源包6

    GiftedMotion是一个很小的,免费而且易于使用图像互换格式动画是能够设计一个有趣的动画了一系列的数字图像。使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的...

    java开源包5

    GiftedMotion是一个很小的,免费而且易于使用图像互换格式动画是能够设计一个有趣的动画了一系列的数字图像。使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的...

    java开源包10

    GiftedMotion是一个很小的,免费而且易于使用图像互换格式动画是能够设计一个有趣的动画了一系列的数字图像。使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的...

    java开源包4

    GiftedMotion是一个很小的,免费而且易于使用图像互换格式动画是能够设计一个有趣的动画了一系列的数字图像。使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的...

    java开源包8

    GiftedMotion是一个很小的,免费而且易于使用图像互换格式动画是能够设计一个有趣的动画了一系列的数字图像。使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的...

    java开源包7

    GiftedMotion是一个很小的,免费而且易于使用图像互换格式动画是能够设计一个有趣的动画了一系列的数字图像。使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的...

    java开源包9

    GiftedMotion是一个很小的,免费而且易于使用图像互换格式动画是能够设计一个有趣的动画了一系列的数字图像。使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的...

    java开源包101

    GiftedMotion是一个很小的,免费而且易于使用图像互换格式动画是能够设计一个有趣的动画了一系列的数字图像。使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的...

    Java资源包01

    GiftedMotion是一个很小的,免费而且易于使用图像互换格式动画是能够设计一个有趣的动画了一系列的数字图像。使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的...

    chef-solo-laptop:Chef Solo 项目来配置我的笔记本电脑

    sudo apt-get install gitGit 用于检索此存储库,其中包含入门所需的所有实用程序脚本、食谱和食谱。 上面的步骤捕获到克隆存储库选择一个合适的目录来克隆这个存储库。 在该目录中执行以下命令 git clone git://...

Global site tag (gtag.js) - Google Analytics