Compass 是首個建立在 Apache Lucene 之上的開源 Java 搜尋引擎框架。它提供了更簡潔的 API、事務支援、物件到索引的映射(支援 Annotation 與 XML)、XML 到索引的映射,並能與 Hibernate、Spring 無縫整合。對於已採用 Hibernate/Spring 技術棧且需要全文搜尋功能的專案,Compass 是極具吸引力的選擇。雖然 Hibernate 3.1+ 內建了 Lucene 整合,但其功能相對簡陋、不支援事務,且依賴較舊的 Lucene 版本;在大型專案中,Compass 仍具不可替代的優勢。
.hbm.xml)。本範例包含四個檔案:實體類別、Compass 配置檔、映射檔、JUnit 測試類別。
Article.javapackage org.li.compass;
import java.util.Date;
public class Article {
private long id;
private String title;
private String content;
private Date publishDate;
// Getter / Setter 省略...
public long getId() { return id; }
public void setId(long id) { this.id = id; }
public String getTitle() { return title; }
public void setTitle(String title) { this.title = title; }
public String getContent() { return content; }
public void setContent(String content) { this.content = content; }
public Date getPublishDate() { return publishDate; }
public void setPublishDate(Date publishDate) { this.publishDate = publishDate; }
}
注意: id 欄位為 Compass 要求的唯一識別碼,類似資料庫主鍵。
compass.cfg.xml<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE compass-core-config PUBLIC
"-//Compass/Compass Core Configuration DTD 1.0//EN"
"https://www.opensymphony.com/compass/dtd/compass-core-configuration.dtd">
<compass-core-config>
<compass name="default">
<connection><file>target/test</file></connection>
<mapping><class>org.li.compass.Article</class></mapping>
</compass>
</compass-core-config>
關鍵設定:<connection> 指定索引儲存目錄;<mapping> 引入映射類別。
Article.cpm.xml<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE compass-core-mapping PUBLIC
"-//Compass/Compass Core Mapping DTD 1.0//EN"
"https://www.opensymphony.com/compass/dtd/compass-core-mapping.dtd">
<compass-core-mapping package="org.li.compass">
<class name="Article">
<id name="id"></id>
<property name="title"><meta-data>titleIndex</meta-data></property>
<property name="content"><meta-data>contentIndex</meta-data></property>
<property name="publishDate"><meta-data>publishDateIndex</meta-data></property>
</class>
</compass-core-mapping>
meta-data 指定底層 Lucene Field 的名稱,若省略則自動生成(如 $article/title)。它決定了屬性在索引中的儲存方式(是否分詞、是否儲存等)。
import org.compass.core.*;
import org.junit.Test;
import java.util.Date;
public class CompassTest {
@Test
public void insertArticle() {
CompassConfiguration conf = new CompassConfiguration().configure().addClass(Article.class);
Compass compass = conf.buildCompass();
CompassSession session = compass.openSession();
CompassTransaction tx = session.beginTransaction();
Article article = new Article();
article.setId(1);
article.setTitle("學習 Compass");
article.setContent("Compass 是第一個基於 Lucene 的 Java 開源框架");
article.setPublishDate(new Date());
session.save(article);
tx.commit();
session.close();
}
@Test
public void loadArticle() {
CompassConfiguration conf = new CompassConfiguration().configure().addClass(Article.class);
Compass compass = conf.buildCompass();
CompassSession session = compass.openSession();
CompassTransaction tx = session.beginTransaction();
Article article = (Article) session.load(Article.class, 1L);
System.out.println("Title: " + article.getTitle());
System.out.println("Content: " + article.getContent());
System.out.println("Publish Date: " + article.getPublishDate());
tx.commit();
session.close();
}
}
Title: 學習 Compass
Content: Compass 是第一個基於 Lucene 的 Java 開源框架
Publish Date: Sat Sep 23 00:51:35 CST 2006
Compass 索引本質上是 Lucene 索引,可直接用 Lucene API 讀取驗證:
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.Hits;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import java.io.IOException;
import org.apache.lucene.queryParser.ParseException;
@Test
public void verifyWithLucene() throws ParseException, IOException {
QueryParser parser = new QueryParser("titleIndex", new StandardAnalyzer());
Query query = parser.parse("compass");
IndexSearcher searcher = new IndexSearcher("target/test/index/article");
Hits hits = searcher.search(query);
for (int i = 0; i < hits.length(); i++) {
System.out.println(hits.doc(i).get("contentIndex"));
}
}
Compass 支援三種配置方式:
CompassTransaction,確保索引一致性。CompassSession 非線程安全,請在 ThreadLocal 或請求範圍內管理。compass.getIndexManager().optimize() 整理索引片段。LocalCompassBean 由 Spring 容器管理生命週期,配合 CompassTemplate 簡化程式碼。Compass 以「物件導向」方式封裝 Lucene,讓 Java 開發者能以熟悉的 Hibernate 風格快速構建企業級搜尋功能,是舊版專案遷移或新專案選型的有力候選。