lucene、solr全文搜索

lucene、solr全文搜索

lucene是一款搜索引擎技術,並非產品,而solr是搜索引擎所在服務器。

應用場景:

1:網站頭部的搜索
2:APP端頭部搜索
3:做成搜索產品


  • 簡介:

    Lucene是一個全文搜索框架,而不是應用產品。因此它並不像www.baidu.com 或者google Desktop那麼拿來就能用,它只是提供了一種工具讓你能實現這些產品。

  • lucene的工作方式

    lucene提供的服務實際包含兩部分:一入一出。所謂入是寫入,即將你提供的源(本質是字符串)寫入索引或者將其從索引中刪除;所謂出是讀出,即向用戶提供全文搜索服務,讓用戶可以通過關鍵詞定位源。

  • 寫入流程

    源字符串首先經過analyzer處理,包括:分詞,分成一個個單詞;去除stopword(可選),將源中需要的信息加入Document的各個Field中,並把需要索引的Field索引起來,把需要存儲的Field存儲起來,將索引寫入存儲器,存儲器可以是內存或磁盤

  • 讀出流程

    用戶提供搜索關鍵詞,經過analyzer處理,對處理後的關鍵詞搜索索引找出對應的Document,用戶根據需要從找到的Document中提取需要的Field

  • 概念

    analyzer:

    Analyzer是分析器,它的作用是把一個字符串按某種規則劃分成一個個詞語,並去除其中的無效詞語,這裏說的無效詞語是指英文中的“of”、“the”,中文中的“的”、“地”等詞語,這些詞語在文章中大量出現,但是本身不包含什麼關鍵信息,去掉有利於縮小索引文件、提高效率、提高命中率

    document:

    用戶提供的源是一條條記錄,它們可以是文本文件、字符串或者數據庫表的一條記錄等等。一條記錄經過索引之後,就是以一個Document的形式存儲在索引文件中的。用戶進行搜索,也是以Document列表的形式返回

    field:

    一個Document可以包含多個信息域,例如一篇文章可以包含“標題”、“正文”、“最後修改時間”等信息域,這些信息域就是通過Field在Document中存儲的。    Field有兩個屬性可選:存儲和索引。通過存儲屬性你可以控制是否對這個Field進行存儲;通過索引屬性你可以控制是否對該Field進行索引。這看起來似乎有些廢話,事實上對這兩個屬性的正確組合很重要,下面舉例說明:還是以剛纔的文章爲例子,我們需要對標題和正文進行全文搜索,所以我們要把索引屬性設置爲真,同時我們希望能直接從搜索結果中提取文章標題,所以我們把標題域的存儲屬性設置爲真,但是由於正文域太大了,我們爲了縮小索引文件大小,將正文域的存儲屬性設置爲假,當需要時再直接讀取文件;我們只是希望能從搜索解果中提取最後修改時間,不需要對它進行搜索,所以我們把最後修改時間域的存儲屬性設置爲真,索引屬性設置爲假。上面的三個域涵蓋了兩個屬性的三種組合,還有一種全爲假的沒有用到,事實上Field不允許你那麼設置,因爲既不存儲又不索引的域是沒有意義的

lucene入門示例

1:新建一個工程
2:導入所需jar包
  • 入庫

    1:新建一個入庫的實體對象

    2:入庫IndexWrite

    代碼如下:

    /**
     * 文檔
     * @author likang
     * @date   2017-12-22 上午9:50:21
     */
    public class Ariclte implements Serializable{
    
        private static final long serialVersionUID = 1L;
    
        private Long aid;
        private String title;
        private String context;
        public Long getAid() {
            return aid;
        }
        public void setAid(Long aid) {
            this.aid = aid;
        }
        public String getTitle() {
            return title;
        }
        public void setTitle(String title) {
            this.title = title;
        }
        public String getContext() {
            return context;
        }
        public void setContext(String context) {
            this.context = context;
        }
    }
    
    /**
     * 入庫:將一篇文件存儲到搜索庫中
     * 出庫:根據關鍵詞,從搜索庫中搜索對應的匹配信息
     * @author likang
     * @date   2017-12-22 上午9:49:26
     */
    public class HelloLucene {
    
        /**
         * 入庫
         * @throws Exception 
         */
        @Test
        public void createIndex() throws Exception{
    
            //初始化數據文章
            Ariclte ariclte = new Ariclte();
            ariclte.setAid(Long.valueOf(1));
            ariclte.setTitle("Lucene是一款很好的搜索引擎");
            ariclte.setContext("Lucene是一款搜索引擎技術,產品有百度,谷歌等");
    
            Directory directory = FSDirectory.open(new File("./indexLucene"));//創建搜索庫路徑目錄
            Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_30);//搜索庫的分詞器
            /**
             * MaxFieldLength.LIMITED:文章長度有限制
             *              UNLIMITED:無限制
             */
            //lucene中入庫的核心接口API
            IndexWriter indexWriter = new IndexWriter(directory, analyzer, MaxFieldLength.LIMITED);
    
            /**
             * Index:
             *      NOT_ANALYZED:代表支持索引,不支持分詞,不支持創建對象,不支持存儲
             *      ANALYZED:代表支持索引,支持分詞,支持創建對象,支持存儲
             *      ANALYZED_NO_NORMS:代表支持索引,支持分詞,不支持創建對象,不支持存儲
             *      NOT_ANALYZED_NO_NORMS:代表支持索引,不支持分詞,不支持創建對象
             *       NO:都不支持
             * 
             * Store:
             *      YES:存儲
             *      NO:不存儲
             * 
             */
    
            Field field1 = new Field("aid", ariclte.getAid().toString(), Store.YES, Index.NOT_ANALYZED);
            Field field2 = new Field("title", ariclte.getTitle(), Store.YES, Index.NO);
            Field field3 = new Field("context", ariclte.getContext(), Store.YES, Index.ANALYZED);
    
            Document document = new Document();
            document.add(field1);
            document.add(field2);
            document.add(field3);
    
            //將document,寫入到搜索庫中
            indexWriter.addDocument(document);
            //關閉搜索庫
            indexWriter.close();
        }
    }
    
  • 出庫

    /**
     * 出庫
     *  根據關鍵詞---匹配3個
     * @throws Exception 
     */
    @Test
    public void searchIndex() throws Exception{
        //獲取搜索庫的位置
        Directory directory = FSDirectory.open(new File("./indexLucene"));
        //搜索庫的分詞器
        Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_30);
    
        //lucene搜索出庫API
        IndexSearcher indexSearcher = new IndexSearcher(directory);
        /**
         * 第一個參數代表之前的庫版本信息
         * 第二參數代表要搜索的字段
         * 第三個參數代表使用的分詞器
         */
        QueryParser queryParser = new QueryParser(Version.LUCENE_30, "context", analyzer);
        //輸入的關鍵詞
        Query query = queryParser.parse("Lucene");
    
        /**
         * 第一個參數代表搜索的關鍵詞
         * 第二個參數代表根據關鍵詞匹配顯示的個數
         */
        TopDocs topDocs = indexSearcher.search(query, 3);
        //所有搜索對象--集合/數組中
        ScoreDoc[] sds = topDocs.scoreDocs;
        List<Ariclte> list = new ArrayList<Ariclte>();
        for (ScoreDoc sd : sds) {
            int index = sd.doc;//文章對應的下標
            Document document = new Document();
            document = indexSearcher.doc(index);
            Ariclte ariclte = new Ariclte();
            ariclte.setAid(Long.valueOf(document.get("aid").toString()));
            ariclte.setTitle(document.get("title"));
            ariclte.setContext(document.get("context"));
            list.add(ariclte);
        }
    
        if (list != null && list.size() > 0) {
            for (int i = 0; i < list.size(); i++) {
                System.out.println("標題:"+list.get(i).getTitle());
                System.out.println("簡短標題:"+list.get(i).getContext());
                System.out.println("點擊進入:www.baidu.com");
            }
        }
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章