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(); } } }
转载请标明出处 http://blog.csdn.net/shimiso
技术交流群:361579846