Compass入门指南(二)

本文介绍如何使用Compass框架对数据库进行索引,并演示了通过Java实现的书籍搜索应用。涉及Compass安装配置、实体注解定义及索引、搜索操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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(书籍)类,这个类就是我们要搜索的对象,其完整代码如下:

Java代码 复制代码
  1. importorg.compass.annotations.Index;
  2. importorg.compass.annotations.Searchable;
  3. importorg.compass.annotations.SearchableId;
  4. importorg.compass.annotations.SearchableProperty;
  5. importorg.compass.annotations.Store;
  6. @Searchable
  7. publicclassBook{
  8. privateStringid;//编号
  9. privateStringtitle;//标题
  10. privateStringauthor;//作者
  11. privatefloatprice;//价格
  12. publicBook(){
  13. }
  14. publicBook(Stringid,Stringtitle,Stringauthor,floatprice){
  15. super();
  16. this.id=id;
  17. this.title=title;
  18. this.author=author;
  19. this.price=price;
  20. }
  21. @SearchableId
  22. publicStringgetId(){
  23. returnid;
  24. }
  25. @SearchableProperty(boost=2.0F,index=Index.TOKENIZED,store=Store.YES)
  26. publicStringgetTitle(){
  27. returntitle;
  28. }
  29. @SearchableProperty(index=Index.TOKENIZED,store=Store.YES)
  30. publicStringgetAuthor(){
  31. returnauthor;
  32. }
  33. @SearchableProperty(index=Index.NO,store=Store.YES)
  34. publicfloatgetPrice(){
  35. returnprice;
  36. }
  37. publicvoidsetId(Stringid){
  38. this.id=id;
  39. }
  40. publicvoidsetTitle(Stringtitle){
  41. this.title=title;
  42. }
  43. publicvoidsetAuthor(Stringauthor){
  44. this.author=author;
  45. }
  46. publicvoidsetPrice(floatprice){
  47. this.price=price;
  48. }
  49. @Override
  50. publicStringtoString(){
  51. return"["+id+"]"+title+"-"+author+"$"+price;
  52. }
  53. }
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类,该类封装了对索引库的一些操作,包括新建索引,删除索引,重建索引,搜索等等。完整代码如下:

Java代码 复制代码
  1. importjava.util.ArrayList;
  2. importjava.util.Collections;
  3. importjava.util.List;
  4. importorg.compass.annotations.config.CompassAnnotationsConfiguration;
  5. importorg.compass.core.Compass;
  6. importorg.compass.core.CompassHits;
  7. importorg.compass.core.CompassSession;
  8. importorg.compass.core.CompassTransaction;
  9. publicclassSearcher
  10. {
  11. protectedCompasscompass;
  12. publicSearcher()
  13. {
  14. }
  15. /**
  16. *初始化Compass
  17. *@parampath
  18. */
  19. publicSearcher(Stringpath)
  20. {
  21. compass=newCompassAnnotationsConfiguration().setConnection(path).addClass(Book.class).setSetting("compass.engine.highlighter.default.formatter.simple.pre","<fontcolor='red'>").setSetting(
  22. "compass.engine.highlighter.default.formatter.simple.post","</font>").buildCompass();
  23. Runtime.getRuntime().addShutdownHook(newThread()
  24. {
  25. publicvoidrun()
  26. {
  27. compass.close();
  28. }
  29. });
  30. }
  31. /**
  32. *新建索引
  33. *@parambook
  34. */
  35. publicvoidindex(Bookbook)
  36. {
  37. CompassSessionsession=null;
  38. CompassTransactiontx=null;
  39. try
  40. {
  41. session=compass.openSession();
  42. tx=session.beginTransaction();
  43. session.create(book);
  44. tx.commit();
  45. }catch(RuntimeExceptione)
  46. {
  47. if(tx!=null)
  48. tx.rollback();
  49. throwe;
  50. }finally
  51. {
  52. if(session!=null)
  53. {
  54. session.close();
  55. }
  56. }
  57. }
  58. /**
  59. *删除索引
  60. *@parambook
  61. */
  62. publicvoidunIndex(Bookbook)
  63. {
  64. CompassSessionsession=null;
  65. CompassTransactiontx=null;
  66. try
  67. {
  68. session=compass.openSession();
  69. tx=session.beginTransaction();
  70. session.delete(book);
  71. tx.commit();
  72. }catch(RuntimeExceptione)
  73. {
  74. tx.rollback();
  75. throwe;
  76. }finally
  77. {
  78. if(session!=null)
  79. {
  80. session.close();
  81. }
  82. }
  83. }
  84. /**
  85. *重建索引
  86. *@parambook
  87. */
  88. publicvoidreIndex(Bookbook)
  89. {
  90. unIndex(book);
  91. index(book);
  92. }
  93. /**
  94. *搜索
  95. *@paramqueryString
  96. *@return
  97. */
  98. publicList<Book>search(StringqueryString)
  99. {
  100. CompassSessionsession=null;
  101. CompassTransactiontx=null;
  102. try
  103. {
  104. session=compass.openSession();
  105. tx=session.beginTransaction();
  106. CompassHitshits=session.find(queryString);
  107. intn=hits.length();
  108. if(0==n)
  109. {
  110. returnCollections.emptyList();
  111. }
  112. List<Book>books=newArrayList<Book>();
  113. for(inti=0;i<n;i++)
  114. {
  115. books.add((Book)hits.data(i));
  116. }
  117. hits.close();
  118. tx.commit();
  119. returnbooks;
  120. }catch(RuntimeExceptione)
  121. {
  122. tx.rollback();
  123. throwe;
  124. }finally
  125. {
  126. if(session!=null)
  127. {
  128. session.close();
  129. }
  130. }
  131. }
  132. }
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();
			}
		}
	}
}


步骤五:新建一个测试类进行测试.完整源码如下:

Java代码 复制代码
  1. importjava.io.BufferedReader;
  2. importjava.io.InputStreamReader;
  3. importjava.util.ArrayList;
  4. importjava.util.List;
  5. importjava.util.UUID;
  6. publicclassMain
  7. {
  8. staticList<Book>db=newArrayList<Book>();
  9. staticSearchersearcher=newSearcher("E:/index");
  10. publicstaticvoidmain(String[]args)
  11. {
  12. add(newBook(UUID.randomUUID().toString(),"ThinkinginJava","Bruce",109.0f));
  13. add(newBook(UUID.randomUUID().toString(),"EffectiveJava","Joshua",12.4f));
  14. add(newBook(UUID.randomUUID().toString(),"JavaThreadPrograming","Paul",25.8f));
  15. intn;
  16. do
  17. {
  18. n=displaySelection();
  19. switch(n)
  20. {
  21. case1:
  22. listBooks();
  23. break;
  24. case2:
  25. addBook();
  26. break;
  27. case3:
  28. deleteBook();
  29. break;
  30. case4:
  31. searchBook();
  32. break;
  33. case5:
  34. return;
  35. }
  36. }while(n!=0);
  37. }
  38. staticintdisplaySelection()
  39. {
  40. System.out.println("\n==select==");
  41. System.out.println("1.Listallbooks");
  42. System.out.println("2.Addbook");
  43. System.out.println("3.Deletebook");
  44. System.out.println("4.Searchbook");
  45. System.out.println("5.Exit");
  46. intn=readKey();
  47. if(n>=1&&n<=5)
  48. returnn;
  49. return0;
  50. }
  51. /**
  52. *增加一本书到数据库和索引中
  53. *@parambook
  54. */
  55. privatestaticvoidadd(Bookbook)
  56. {
  57. db.add(book);
  58. searcher.index(book);
  59. }
  60. /**
  61. *打印出数据库中的所有书籍列表
  62. */
  63. publicstaticvoidlistBooks()
  64. {
  65. System.out.println("==Database==");
  66. intn=1;
  67. for(Bookbook:db)
  68. {
  69. System.out.println(n+")"+book);
  70. n++;
  71. }
  72. }
  73. /**
  74. *根据用户录入,增加一本书到数据库和索引中
  75. */
  76. publicstaticvoidaddBook()
  77. {
  78. Stringtitle=readLine("Title:");
  79. Stringauthor=readLine("Author:");
  80. Stringprice=readLine("Price:");
  81. Bookbook=newBook(UUID.randomUUID().toString(),title,author,Float.valueOf(price));
  82. add(book);
  83. }
  84. /**
  85. *删除一本书,同时删除数据库,索引库中的
  86. */
  87. publicstaticvoiddeleteBook()
  88. {
  89. listBooks();
  90. System.out.println("Bookindex:");
  91. intn=readKey();
  92. Bookbook=db.remove(n-1);
  93. searcher.unIndex(book);
  94. }
  95. /**
  96. *根据输入的关键字搜索书籍
  97. */
  98. publicstaticvoidsearchBook()
  99. {
  100. StringqueryString=readLine("Enterkeyword:");
  101. List<Book>books=searcher.search(queryString);
  102. System.out.println("====searchresults:"+books.size()+"====");
  103. for(Bookbook:books)
  104. {
  105. System.out.println(book);
  106. }
  107. }
  108. publicstaticintreadKey()
  109. {
  110. BufferedReaderreader=newBufferedReader(newInputStreamReader(System.in));
  111. try
  112. {
  113. intn=reader.read();
  114. n=Integer.parseInt(Character.toString((char)n));
  115. returnn;
  116. }catch(Exceptione)
  117. {
  118. thrownewRuntimeException();
  119. }
  120. }
  121. publicstaticStringreadLine(Stringpropt)
  122. {
  123. System.out.println(propt);
  124. BufferedReaderreader=newBufferedReader(newInputStreamReader(System.in));
  125. try{
  126. returnreader.readLine();
  127. }catch(Exceptione)
  128. {
  129. thrownewRuntimeException();
  130. }
  131. }
  132. }
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();
		}
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值