天天看點

lucene的自我學習小結,大牛路過請過指教 - da_niu_niu

lucene的自我學習小結,大牛路過請過指教

1.什麼是全文檢索?

全文檢索:就是對海量非結構資料進行建立索引,在對建立的索引進行查詢的過程。

例如:圖書館找書,商品的快速查找等等

全文檢索的應用場景?

一般用在搜尋引擎,和一些站内搜尋中海量資料的優化查詢速度的應用。

為什麼要學習全文檢索?

為了解決海量資料查詢慢的問題,

資料一般分為結構性資料,非結構性資料

結構性資料是:長度固定,資料類型固定,結構固定,例如我們學習的mysql,oracle資料庫表資料

非結構性資料:一般是,長度不固定,類型不固定,大小不固定。例如我們的一些文檔,比如.txt .pdf .java 等等的文檔。

2.如何給海量資料建立索引,實作快速查找的流程?

其中主要有三種

  1. 通過持久層架構對資料庫資料的查詢
  2. 通過IO流建讀取文檔給文檔建建立索引,根據索引實作快速的查找
  3. 對海量的資料進行檔案對象的建立,建立索引對象,讀取源檔案的資料,将源檔案的對象進行周遊,擷取每一個源檔案的資訊,建立文檔對象将每一個源檔案資訊存放進文檔對象中,然後通過索引對象調用存儲文檔對象的方法,将存儲文檔資訊的文檔對象存入索引庫,

其中重點的是将具有統一查詢條件資訊,對應的文檔的路徑按照key對應多個value 的方式進行存儲,例如:D://aaa.bbb.ccc.ddd.text,D://aaa.bbb.ccc.eee.txt。同時為了查詢的效率橫向搜尋更簡潔,可以将key值進行切割,分成多個key對應一個value,例如将搜尋條件‘’JAVA程式設計思想”進行切割,JAVA,程式設計,思想,三個key對應一個VALUE。

3.給源檔案資料建立索引庫的基本步驟

  1. 建立directory檔案對象,指定索引庫儲存的位置
  2. 建立indexwriter對象(又稱為索對象),擷取檔案資料的名稱,大小,路徑,内容。
  3. 讀取源檔案的資訊,将擷取的所有源檔案進行周遊
  4. 擷取每一個源檔案的資訊
  5. 建立文檔對象,将每一個源檔案的資訊存入文檔中
  6. 索引對象調用添加文檔對象對應的方法,将存有文檔資訊的文檔對象存入索引庫中
  7. 關閉indexWriter對象
    //建立一個director對象
            //儲存在磁盤中
            //Directory directory =new RAMDirectory();
            Directory directory=   FSDirectory.open(new File("D:\\temp\\index").toPath());
            //建立indexWriter索引對象
            IndexWriterConfig config = new IndexWriterConfig(new IKAnalyzer());
            IndexWriter indexWriter = new IndexWriter(directory,config);
            //讀取源檔案的資料
            File file = new File("D:\\品優購\\lucene2018\\02.參考資料\\searchsource");
            File[] files = file.listFiles();
            for (File file1 : files) {
                String file1Name = file1.getName();
                String file1Path = file1.getPath();
                String fileContent = FileUtils.readFileToString(file1, "UTF-8");
                long fileSize = FileUtils.sizeOf(file1);
                //擷取索引庫的檔案資訊
                TextField fileName = new TextField("name",file1Name, Field.Store.YES);
                TextField filePath = new TextField("path",file1Path, Field.Store.YES);
                TextField fileContent1 = new TextField("content",fileContent, Field.Store.YES);
                TextField fileSize1 = new TextField("size",fileSize+"", Field.Store.YES);
                //建立Document文檔對象
                Document document = new Document();
                //将讀取的源檔案資料存入document文檔對象中
                document.add(fileName);
                document.add(filePath);
                document.add(fileContent1);
                document.add(fileSize1);
                //将document對象存入索引資料庫中
                indexWriter.addDocument(document);
            }
           //關閉流對象
            indexWriter.close();      

4.代碼實作查詢索引庫的流程分析

  1. 建立一個director對象,指定索引庫的位置
  2. 建立一個indexreader對象
  3. 建立一個index Searcher對象,構造方法中的參數index Reader對象
  4. 建立一個Queary對象,TermQueary(建立根據關鍵詞查詢的對象)
  5. 執行查詢,得到一個TopDocs對象-->(得到查詢的結果,其中有兩個部分,一個是查詢結果的總記錄數,一個是文檔的清單資訊)
  6. 取查詢結果的總記錄數
  7. 取文檔清單
  8. 列印文檔清單
  9. 關閉index Reader對象
    //建立director對象
            Directory directory=   FSDirectory.open(new File("D:\\temp\\index").toPath());
            //建立讀取director對象的IndexReader對象
            IndexReader indexReader = DirectoryReader.open(directory);
            //建立一個indexSearch對象,構造方法傳入參數是IndexReader對象
            IndexSearcher indexSearcher = new IndexSearcher(indexReader);
            //建立一個Queary對象,TreamQueary
            TermQuery termQuery = new TermQuery(new Term("content", "java"));
            //執行查詢,得到一個TopDocs對象
            TopDocs docs = indexSearcher.search(termQuery, 10);
            //取查詢結果的總記錄數
            System.out.println("查詢總記錄數:"+docs.totalHits);
            //取文檔清單
            ScoreDoc[] scoreDocs = docs.scoreDocs;
            for (ScoreDoc scoreDoc : scoreDocs) {
                int id = scoreDoc.doc;
                //擷取文檔對象
                Document document = indexSearcher.doc(id);
                //列印文檔清單
                System.out.println(document.get("name"));
                System.out.println(document.get("path"));
               // System.out.println(document.get("content"));
                System.out.println(document.get("size"));
                System.out.println("-----------------------");
    ​
            }
            //關閉IndexReader流
            indexReader.close();      

5.檢視分析器的分析效果及實作步驟

最初的分詞器: 庖丁解牛分詞器, 近幾年才出的: IKanlays分詞器

預設使用的分析器是:standarAnalyzer

使用Analyzer對象的tokenStream方法傳回一個tokenStream對象,該對象中包含了最終分詞的效果。

實作步驟:

  1. 建立一個Analyzer(分析器)對象,StandardAnalyzer對象-->預設的标準分詞器(此處我們可以使用建立IK分詞器的對象--new IKAnalyzer(),這樣分詞出來的資訊會更實際化一些)
  2. 使用分析器對象的tokenStream的方法獲得一個TokenStream對象
  3. 向TokenStream對象設定一個引用,相當于設定一個指針,擷取指針就可以擷取指針對應的值。
  4. 調用TokenStream對象的rest方法,如果不調用就會抛異常,必須調用,作用是将随機的指針設定到第一的位置
  5. 使用while 循環百周遊TokenStream對象
  6. 關閉TokenStream對象
      1. 建立一個Analyzer(分析器)對象,StandardAnalyzer對象-->标準分詞器
           // StandardAnalyzer analyzer = new StandardAnalyzer();
            IKAnalyzer analyzer = new IKAnalyzer();
    //        2. 使用分析器對象的tokenStream的方法獲得一個TokenStream對象
            TokenStream tokenStream = analyzer.tokenStream("", "老師,我王旭要坐你腿上玩評優購");
    //        3. 向TokenStream對象設定一個引用,相當于設定一個指針,擷取指針就可以擷取指針對應的值。
            CharTermAttribute charTermAttribute = tokenStream.addAttribute(CharTermAttribute.class);
    //        4. 調用TokenStream對象的rest方法,如果不調用就會抛異常,必須調用,作用是将随機的指針設定到第一的位置
            tokenStream.reset();
    //        5. 使用while 循環百周遊TokenStream對象
            while(tokenStream.incrementToken()){
                System.out.println(charTermAttribute.toString());
            }
    //        6. 關閉TokenStream對象
            tokenStream.close()      

6.對索引庫資訊進行CRUD操作

此時在類中的重複代碼比較備援,可以使用前置注解@Before抽取重複代碼塊,簡化代碼書寫。

   @Before
    public void init() throws IOException {
      indexWriter = new IndexWriter(FSDirectory.open(new File("D:\\temp\\index").toPath()), new IndexWriterConfig(new IKAnalyzer()));
    }      

對索引庫添加文檔資訊的實作步驟

  1. 建立director檔案對象,并指定所應庫的位置
  2. 建立IndexWriter對象
  3. 建立文檔對象
  4. 向文檔對象中存入域資訊
  5. 将文檔資訊寫入索引庫(indexWriter對象通過addDocument()方法将文檔資訊存儲進索引庫中)
  6. 釋放indexWriter對象

    對索引庫資訊進行删除的基本思路步驟

    1. 建立director對象,并指定索引庫的位置
    2. 建立indexWriter對象
    3. 使用indexWriter對象調用deleteAll方法。
    4. 釋放indexWriter對象

多索引庫資訊的更新操作基本實作步驟

  1. 建立indexWriter對象,指定索引庫的位置
  2. 建立文檔Document對象
  3. 向文檔中添加域資訊
  4. 使用indexWriter獨享調用update方法(傳入需要被修改的檔案的關鍵詞資訊:new Term());
  5. 釋放indexWriter對象

未完待續,其中還有兩種查詢方法,晚點再補上。