1. 程式人生 > >Compass 更智慧的搜尋引擎(1)--入門

Compass 更智慧的搜尋引擎(1)--入門

學完了前面的Lucene系列教程:

Lucene確實是個好東西,適用性也很強。但是需要對待索引的資料手動的封裝,每次都需要從底層開始一點點的設計。對於一個工作量很大的專案而言,簡直就是噩夢。所以,我們對於Lucene,瞭解其工作原理就行了。實際中開發靠得住的還是易用性強的框架。這同時也給我們這些開發人員提了個醒不是?易用.下面就來分享一個更好用的全文搜尋框架。Compass,一個基於Lucene而又高於Lucene的好框架!

準備工作

引入Compass

由於Compass是基於Lucene的,所以我們需要引入Lucene的支援。文中可以看到lucene的資料夾。
Lucene依賴

最後一點,那就是對於中文支援的依賴。使用適合漢語特點的分詞器將能大大的提高我們的全文搜尋的精準度。

適合漢語的Lucene拓展分詞器下載

Compass工作原理

圖解工作原理。

引用網上的一張圖。
Compass工作原理

Compass和Hibernate的對比

主配置對比分析 Hibernate Compass
主配置檔名稱 hibernate.cfg.xml compass.cfg.xml
主配置檔案所在目錄 src目錄 src目錄
連線資訊 資料庫的連線資訊 索引庫的連線資訊<connection><file path="indexDir"></connection>
宣告對映檔案 mapper標籤宣告 mapping標籤宣告,標註Bean的全名即可
其他配置 二級快取,顯示SQL語句,自動建表等 其他配置,分詞器、高亮器等

Compass工作流程

Created with Raphaël 2.1.0載入配置資訊`Configuration cfg = new Configuration().configure(); //預設載入hibernate.cfg.xml`獲得Session物件`SessionFactory sessionFactory =cfg.buildSessionFactory(); //全域性唯一`藉助session物件完成業務邏輯,包括過濾,排序,各種查詢等等`Session session = sessionFactory.openSession();`
歸還session物件,資源`session.close(); //關閉session`完成Compass業務邏輯

例項分析

專案目錄

專案目錄分析

建立Bean物件Article.java

/**
 * @Date 2016年8月2日
 *
 * @author Administrator
 */
package domain;

import org.compass.annotations.ExcludeFromAll;
import org.compass.annotations.Index;
import org.compass.annotations.Searchable;
import org.compass.annotations.SearchableBoostProperty;
import org.compass.annotations.SearchableId;
import org.compass.annotations.SearchableProperty;
import org.compass.annotations.Store;

/**
 * 
 * Compass的對映配置要求
 * 
 * 在實體類上面有一個@Searchable註解<br>
 * 
 * 在屬性上面,至少有一個有@SearchableId
 * 
 * 其他的屬性只需要是@SearchableProperty即可
 * 
 * 
 * 
 * @author 郭瑞彪
 */
@Searchable
public class Article {
    @SearchableId
    private Integer id;

    @SearchableProperty(store = Store.YES, index = Index.ANALYZED)
    private String title;
    @SearchableProperty(store = Store.YES, index = Index.ANALYZED)
    private String content;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    @Override
    public String toString() {
        return "Article [id=" + id + ", title=" + title + ", content=" + content + "]";
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

}

CompassUtils.java

/**
 * @Date 2016年8月2日
 *
 * @author Administrator
 */
package util;

import org.compass.core.Compass;
import org.compass.core.config.CompassConfiguration;

/**
 * @author 郭瑞彪
 *
 */
public class CompassUtils {
    private static Compass compassSessionFactory;

    static{
        CompassConfiguration cfg = new CompassConfiguration().configure();
        compassSessionFactory = cfg.buildCompass();
    }


    public static Compass getCompassSessionFactory() {
        return compassSessionFactory;
    }

}

compass.cfg.xml

<?xml version="1.0" encoding="UTF-8" ?>
<compass-core-config xmlns="http://www.compass-project.org/schema/core-config"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.compass-project.org/schema/core-config
           http://www.compass-project.org/schema/compass-core-config-2.2.xsd">

    <compass name="default">
        <!-- 連線資訊,好比資料庫的連線資訊 -->
        <connection>
            <file path="./indexDir/" />
        </connection>

        <!-- 對映資訊,好比Hibernate的對映關係 -->
        <mappings>
            <class name="domain.Article" />
        </mappings>

</compass-core-config>   

測試程式碼

/**
 * @Date 2016年8月2日
 *
 * @author Administrator
 */
package main;

import java.util.ArrayList;
import java.util.List;

import org.compass.core.Compass;
import org.compass.core.CompassHits;
import org.compass.core.CompassSession;
import org.compass.core.CompassTransaction;
import org.junit.Test;

import domain.Article;
import util.CompassUtils;

/**
 * @author 郭瑞彪
 *
 */
public class HelloWorld {

    @Test
    public void createIndex() throws Exception {
        // 模擬一條文章資料
        Article a = new Article();
        a.setId(1);
        a.setTitle("全文檢索");
        a.setContent("我們主要是做站內搜尋(或叫系統內搜尋),即對系統內的資源進行搜尋");

        // 建立索引
        Compass compassSessionFactory = CompassUtils.getCompassSessionFactory();

        CompassSession session = compassSessionFactory.openSession();
        CompassTransaction tx = session.beginTransaction();
        session.create(a);
        tx.commit();
        session.close();
    }

    @Test
    public void search() throws Exception {

        String queryString = "資源";

        // 查詢,得到結果
        List<Article> articles = new ArrayList<Article>();

        // 建立索引
        Compass compassSessionFactory = CompassUtils.getCompassSessionFactory();

        CompassSession session = compassSessionFactory.openSession();
        CompassTransaction tx = session.beginTransaction();
        CompassHits hits = session.find(queryString);
        for (int i = 0; i < hits.length(); i++) {
            Article a = (Article) hits.data(i);
            articles.add(a);
        }
        tx.commit();
        session.close();

        // 顯示結果
        System.out.println(articles.toString());
        for (Article a : articles) {
            System.out.println("-----------搜尋結果如下-----------------");
            System.out.println(">>>id: " + a.getId());
            System.out.println(">>>title:" + a.getTitle());
            System.out.println(">>>content:" + a.getContent());
        }
    }

}

以上,我們就實現了對於Compass的入門級的使用了。是不是很方便呢?