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 Stringid; //编号
- private Stringtitle; //标题
- private Stringauthor; //作者
- private float price; //价格
- public Book(){
- }
- public Book(Stringid,Stringtitle,Stringauthor, float price){
- super ();
- this .id=id;
- this .title=title;
- this .author=author;
- this .price=price;
- }
- @SearchableId
- public StringgetId(){
- return id;
- }
- @SearchableProperty (boost= 2 .0F,index=Index.TOKENIZED,store=Store.YES)
- public StringgetTitle(){
- return title;
- }
- @SearchableProperty (index=Index.TOKENIZED,store=Store.YES)
- public StringgetAuthor(){
- return author;
- }
- @SearchableProperty (index=Index.NO,store=Store.YES)
- public float getPrice(){
- return price;
- }
- public void setId(Stringid){
- this .id=id;
- }
- public void setTitle(Stringtitle){
- this .title=title;
- }
- public void setAuthor(Stringauthor){
- this .author=author;
- }
- public void setPrice( float price){
- this .price=price;
- }
- @Override
- public StringtoString(){
- 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 Compasscompass;
- public Searcher()
- {
- }
- /**
- *初始化Compass
- *@parampath
- */
- public Searcher(Stringpath)
- {
- compass= new CompassAnnotationsConfiguration().setConnection(path).addClass(Book. class ).setSetting( "compass.engine.highlighter.default.formatter.simple.pre" , "<fontcolor='red'>" ).setSetting(
- "compass.engine.highlighter.default.formatter.simple.post" , "</font>" ).buildCompass();
- Runtime.getRuntime().addShutdownHook( new Thread()
- {
- public void run()
- {
- compass.close();
- }
- });
- }
- /**
- *新建索引
- *@parambook
- */
- public void index(Bookbook)
- {
- CompassSessionsession= null ;
- CompassTransactiontx= null ;
- try
- {
- session=compass.openSession();
- tx=session.beginTransaction();
- session.create(book);
- tx.commit();
- } catch (RuntimeExceptione)
- {
- if (tx!= null )
- tx.rollback();
- throw e;
- } finally
- {
- if (session!= null )
- {
- session.close();
- }
- }
- }
- /**
- *删除索引
- *@parambook
- */
- public void unIndex(Bookbook)
- {
- CompassSessionsession= null ;
- CompassTransactiontx= null ;
- try
- {
- session=compass.openSession();
- tx=session.beginTransaction();
- session.delete(book);
- tx.commit();
- } catch (RuntimeExceptione)
- {
- tx.rollback();
- throw e;
- } finally
- {
- if (session!= null )
- {
- session.close();
- }
- }
- }
- /**
- *重建索引
- *@parambook
- */
- public void reIndex(Bookbook)
- {
- unIndex(book);
- index(book);
- }
- /**
- *搜索
- *@paramqueryString
- *@return
- */
- public List<Book>search(StringqueryString)
- {
- CompassSessionsession= null ;
- CompassTransactiontx= null ;
- try
- {
- session=compass.openSession();
- tx=session.beginTransaction();
- CompassHitshits=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 (RuntimeExceptione)
- {
- 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 Searchersearcher= new Searcher( "E:/index" );
- public static void main(String[]args)
- {
- add( new Book(UUID.randomUUID().toString(), "ThinkinginJava" , "Bruce" , 109 .0f));
- add( new Book(UUID.randomUUID().toString(), "EffectiveJava" , "Joshua" , 12 .4f));
- add( new Book(UUID.randomUUID().toString(), "JavaThreadPrograming" , "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.Listallbooks" );
- System.out.println( "2.Addbook" );
- System.out.println( "3.Deletebook" );
- System.out.println( "4.Searchbook" );
- System.out.println( "5.Exit" );
- int n=readKey();
- if (n>= 1 &&n<= 5 )
- return n;
- return 0 ;
- }
- /**
- *增加一本书到数据库和索引中
- *@parambook
- */
- private static void add(Bookbook)
- {
- db.add(book);
- searcher.index(book);
- }
- /**
- *打印出数据库中的所有书籍列表
- */
- public static void listBooks()
- {
- System.out.println( "==Database==" );
- int n= 1 ;
- for (Bookbook:db)
- {
- System.out.println(n+ ")" +book);
- n++;
- }
- }
- /**
- *根据用户录入,增加一本书到数据库和索引中
- */
- public static void addBook()
- {
- Stringtitle=readLine( "Title:" );
- Stringauthor=readLine( "Author:" );
- Stringprice=readLine( "Price:" );
- Bookbook= new Book(UUID.randomUUID().toString(),title,author,Float.valueOf(price));
- add(book);
- }
- /**
- *删除一本书,同时删除数据库,索引库中的
- */
- public static void deleteBook()
- {
- listBooks();
- System.out.println( "Bookindex:" );
- int n=readKey();
- Bookbook=db.remove(n- 1 );
- searcher.unIndex(book);
- }
- /**
- *根据输入的关键字搜索书籍
- */
- public static void searchBook()
- {
- StringqueryString=readLine( "Enterkeyword:" );
- List<Book>books=searcher.search(queryString);
- System.out.println( "====searchresults:" +books.size()+ "====" );
- for (Bookbook:books)
- {
- System.out.println(book);
- }
- }
- public static int readKey()
- {
- BufferedReaderreader= new BufferedReader( new InputStreamReader(System.in));
- try
- {
- int n=reader.read();
- n=Integer.parseInt(Character.toString(( char )n));
- return n;
- } catch (Exceptione)
- {
- throw new RuntimeException();
- }
- }
- public static StringreadLine(Stringpropt)
- {
- System.out.println(propt);
- BufferedReaderreader= new BufferedReader( new InputStreamReader(System.in));
- try {
- return reader.readLine();
- } catch (Exceptione)
- {
- throw new RuntimeException();
- }
- }
- }