lucene的自我學習小結,大牛路過請過指教
1.什麼是全文檢索?
全文檢索:就是對海量非結構資料進行建立索引,在對建立的索引進行查詢的過程。
例如:圖書館找書,商品的快速查找等等
全文檢索的應用場景?
一般用在搜尋引擎,和一些站内搜尋中海量資料的優化查詢速度的應用。
為什麼要學習全文檢索?
為了解決海量資料查詢慢的問題,
資料一般分為結構性資料,非結構性資料
結構性資料是:長度固定,資料類型固定,結構固定,例如我們學習的mysql,oracle資料庫表資料
非結構性資料:一般是,長度不固定,類型不固定,大小不固定。例如我們的一些文檔,比如.txt .pdf .java 等等的文檔。
2.如何給海量資料建立索引,實作快速查找的流程?
其中主要有三種
- 通過持久層架構對資料庫資料的查詢
- 通過IO流建讀取文檔給文檔建建立索引,根據索引實作快速的查找
- 對海量的資料進行檔案對象的建立,建立索引對象,讀取源檔案的資料,将源檔案的對象進行周遊,擷取每一個源檔案的資訊,建立文檔對象将每一個源檔案資訊存放進文檔對象中,然後通過索引對象調用存儲文檔對象的方法,将存儲文檔資訊的文檔對象存入索引庫,
其中重點的是将具有統一查詢條件資訊,對應的文檔的路徑按照key對應多個value 的方式進行存儲,例如:D://aaa.bbb.ccc.ddd.text,D://aaa.bbb.ccc.eee.txt。同時為了查詢的效率橫向搜尋更簡潔,可以将key值進行切割,分成多個key對應一個value,例如将搜尋條件‘’JAVA程式設計思想”進行切割,JAVA,程式設計,思想,三個key對應一個VALUE。
3.給源檔案資料建立索引庫的基本步驟
- 建立directory檔案對象,指定索引庫儲存的位置
- 建立indexwriter對象(又稱為索對象),擷取檔案資料的名稱,大小,路徑,内容。
- 讀取源檔案的資訊,将擷取的所有源檔案進行周遊
- 擷取每一個源檔案的資訊
- 建立文檔對象,将每一個源檔案的資訊存入文檔中
- 索引對象調用添加文檔對象對應的方法,将存有文檔資訊的文檔對象存入索引庫中
- 關閉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.代碼實作查詢索引庫的流程分析
- 建立一個director對象,指定索引庫的位置
- 建立一個indexreader對象
- 建立一個index Searcher對象,構造方法中的參數index Reader對象
- 建立一個Queary對象,TermQueary(建立根據關鍵詞查詢的對象)
- 執行查詢,得到一個TopDocs對象-->(得到查詢的結果,其中有兩個部分,一個是查詢結果的總記錄數,一個是文檔的清單資訊)
- 取查詢結果的總記錄數
- 取文檔清單
- 列印文檔清單
- 關閉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對象,該對象中包含了最終分詞的效果。
實作步驟:
- 建立一個Analyzer(分析器)對象,StandardAnalyzer對象-->預設的标準分詞器(此處我們可以使用建立IK分詞器的對象--new IKAnalyzer(),這樣分詞出來的資訊會更實際化一些)
- 使用分析器對象的tokenStream的方法獲得一個TokenStream對象
- 向TokenStream對象設定一個引用,相當于設定一個指針,擷取指針就可以擷取指針對應的值。
- 調用TokenStream對象的rest方法,如果不調用就會抛異常,必須調用,作用是将随機的指針設定到第一的位置
- 使用while 循環百周遊TokenStream對象
- 關閉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()));
}
對索引庫添加文檔資訊的實作步驟
- 建立director檔案對象,并指定所應庫的位置
- 建立IndexWriter對象
- 建立文檔對象
- 向文檔對象中存入域資訊
- 将文檔資訊寫入索引庫(indexWriter對象通過addDocument()方法将文檔資訊存儲進索引庫中)
-
釋放indexWriter對象
對索引庫資訊進行删除的基本思路步驟
- 建立director對象,并指定索引庫的位置
- 建立indexWriter對象
- 使用indexWriter對象調用deleteAll方法。
- 釋放indexWriter對象
多索引庫資訊的更新操作基本實作步驟
- 建立indexWriter對象,指定索引庫的位置
- 建立文檔Document對象
- 向文檔中添加域資訊
- 使用indexWriter獨享調用update方法(傳入需要被修改的檔案的關鍵詞資訊:new Term());
- 釋放indexWriter對象
未完待續,其中還有兩種查詢方法,晚點再補上。