首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

基於 Java 的搜尋引擎框架:Compass 入門與實戰

     編輯:Java 相關知識

前言:為什麼選擇 Compass?

Compass 是首個建立在 Apache Lucene 之上的開源 Java 搜尋引擎框架。它提供了更簡潔的 API、事務支援、物件到索引的映射(支援 Annotation 與 XML)、XML 到索引的映射,並能與 Hibernate、Spring 無縫整合。對於已採用 Hibernate/Spring 技術棧且需要全文搜尋功能的專案,Compass 是極具吸引力的選擇。雖然 Hibernate 3.1+ 內建了 Lucene 整合,但其功能相對簡陋、不支援事務,且依賴較舊的 Lucene 版本;在大型專案中,Compass 仍具不可替代的優勢。

核心概念

  • CompassConfiguration:框架配置入口,負責載入映射檔、設定索引目錄。
  • Compass:核心介面,代表搜尋引擎實例,線程安全。
  • CompassSession:工作階段,非線程安全,用於執行儲存、載入、查詢等操作。
  • CompassTransaction:事務控制,確保索引操作的原子性。
  • 映射檔:定義 POJO 與索引結構的對應關係(類似 Hibernate 的 .hbm.xml)。

快速上手:Hello World 完整範例

本範例包含四個檔案:實體類別、Compass 配置檔、映射檔、JUnit 測試類別。

1. 實體類別 Article.java

package 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 要求的唯一識別碼,類似資料庫主鍵。

2. 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> 引入映射類別。

3. 映射檔 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)。它決定了屬性在索引中的儲存方式(是否分詞、是否儲存等)。

4. JUnit 測試:寫入與讀取


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

進階:直接使用 Lucene API 驗證索引內容

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 支援三種配置方式:

  1. Annotations:在實體類別上直接標註(最現代、推薦)。
  2. DTD 驗證 XML:本文示範方式,相容性好。
  3. Schema 驗證 XML:結構更嚴格,IDE 支援更好。

最佳實踐建議

  1. 事務邊界清晰:每次業務操作開啟一個 CompassTransaction,確保索引一致性。
  2. Session 管理:CompassSession 非線程安全,請在 ThreadLocal 或請求範圍內管理。
  3. 索引優化:定期呼叫 compass.getIndexManager().optimize() 整理索引片段。
  4. 版本相容:升級 Compass 時注意 Lucene 版本變更,必要時重建索引。
  5. 整合 Spring:生產環境建議使用 LocalCompassBean 由 Spring 容器管理生命週期,配合 CompassTemplate 簡化程式碼。

Compass 以「物件導向」方式封裝 Lucene,讓 Java 開發者能以熟悉的 Hibernate 風格快速構建企業級搜尋功能,是舊版專案遷移或新專案選型的有力候選。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved