lucene學習–建立索引與搜尋

來源:互聯網
上載者:User

首先在E:\TestLucene\workspaceSE路徑下,建立檔案夾indexdocs和3個txt檔案:L1.txt,L2.txt,L3.txt.

L1.txt內容:

111111111111111111111111111111111111111111111111111111111111111111111111111
資訊檢索就是從資訊集合中找出與使用者需求相關的資訊。
被檢索的資訊除了文本外,還有映像、音頻、視頻等多媒體資訊,這裡我們主要來說說文本資訊的檢索。
全文檢索索引:把使用者的查詢請求和全文中的每一詞進行比較,不考慮查詢請求與文本語義上的匹配,
在資訊檢索工具中,全文檢索索引是最具通用性和實用性的。(通俗的講就是匹配關鍵字的)

資料檢索:查詢要求和資訊系統中的資料都遵循一定的格式,具有一定的結構,
允許對特定的欄位檢索,其效能與使用有很大的局限性,並且支援語義匹配。

知識檢索:強調的是基於知識的、語義的匹配(最複雜的,它就相當於我們知道了搜尋問題的答案,
再直接去搜答案的資訊)。

全文檢索索引是指電腦索引程式通過掃描文章中的每一個詞,對每一個詞建立一個索引,
指明該詞在文章中出現的次數和位置,當使用者查詢的時候,檢索程式就根據事先建立好的索引進行尋找,並將尋找的結果反饋給使用者的檢索方式。

資料檢索查詢要求和資訊系統中的資料都遵循一定的格式,具有一定的結構,允許對特定的欄位檢索。
例如,資料均按“時間、人物、地點、事件”的形式儲存,查詢可以為:地點=“北京”。資料檢索的效能取決於所使用的識別欄位的方法和使用者對這種方法的理解,因此具有很大的局限性。

 

L2.txt內容:

 

2222222222222222222222222222222222222222222222222222222222222222222222222
說明:在Internet上採集資訊的軟體被稱為爬蟲或蜘蛛或網路機器人(搜尋引擎外圍的東西),
爬蟲在Internet上訪問每一個網頁,每訪問一個網頁就把其中的內容傳回本機伺服器。
資訊加工的最主要的任務就是為採集到本地的資訊編排索引,為查詢做好準備。
分詞器的作用:分詞器,對文本資源進行切分,將文本按規則切分成一個個進行索引的最小單位(關鍵詞)

 

L3.txt內容:

333333333333333333333333333333333333333333333333333333333333333333333333
中文分詞:中文的分詞比較複雜,因為不是一個字就是一個詞,
而且一個詞在另外一個地方可能不是一個詞,如在“帽子和服裝”中,
“和服”就不是一個詞,對於中文分詞,通常有三種方式:單字分詞、二分法分詞、詞典分詞
單字分詞:就是按照中文一個字一個字的分詞
二分法分詞:按兩個字進行切分
詞典分詞:按某種演算法構造詞,然後去匹配已建好的詞庫集合,如果匹配到就切分出來成為詞語,

 

準備工作完成了,現在看代碼:

File2Document.java

package lucene.study;import java.io.BufferedReader;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.io.InputStreamReader;import java.io.UnsupportedEncodingException;import org.apache.lucene.document.Document;import org.apache.lucene.document.Field;import org.apache.lucene.document.Field.Index;import org.apache.lucene.document.Field.Store;/** * @author xudongwang 2012-2-2 *  *         Email:xdwangiflytek@gmail.com */public class File2Document {/** * File--->Document *  * @param filePath *            File路徑 *  * @return Document對象 */public static Document file2Document(String filePath) {// 檔案要存放:name,content,size,pathFile file = new File(filePath);Document document = new Document();// Store.YES 是否儲存 yes no compress(壓縮之後再存)// Index 是否進行索引 Index.ANALYZED 分詞後進行索引,NOT_ANALYZED 不索引,NOT_ANALYZED// 不分詞直接索引document.add(new Field("name", file.getName(), Field.Store.YES,Field.Index.ANALYZED));document.add(new Field("content", readFileContent(file), Field.Store.YES,Field.Index.ANALYZED));document.add(new Field("size", String.valueOf(file.length()),Field.Store.YES, Field.Index.NOT_ANALYZED));// 不分詞,但是有時需要索引,檔案大小(int)轉換成Stringdocument.add(new Field("path", file.getAbsolutePath(), Field.Store.YES,Field.Index.NOT_ANALYZED));// 不需要根據檔案的路徑來查詢return document;}/** * 49. * 讀取檔案內容 50. * 51. * @param file 52. * File對象 53. * @return File的內容 * 54. */private static String readFileContent(File file) {try {BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));StringBuffer content = new StringBuffer();try {for (String line = null; (line = reader.readLine()) != null;) {content.append(line).append("\n");}} catch (IOException e) {e.printStackTrace();}//try {//byte temp[]=content.toString().getBytes("UTF-8");//String tt=new String(temp,"gb2312");//System.out.println(tt);//} catch (UnsupportedEncodingException e) {//e.printStackTrace();//}return content.toString();} catch (FileNotFoundException e) {e.printStackTrace();}return null;}/** * <pre> * 擷取name屬性值的兩種方法     * 1.Filed field = document.getFiled("name");     *         field.stringValue();     * 2.document.get("name"); * </pre> *  * @param document */public static void printDocumentInfo(Document document) {// TODO Auto-generated method stubSystem.out.println("索引name -->" + document.get("name"));//System.out.println("content -->" + document.get("content"));System.out.println("索引path -->" + document.get("path"));System.out.println("索引size -->" + document.get("size"));}}

 

FirstLucene.java

 

package lucene.study;import java.io.File;import org.apache.lucene.analysis.Analyzer;import org.apache.lucene.analysis.standard.StandardAnalyzer;import org.apache.lucene.document.Document;import org.apache.lucene.document.Field;import org.apache.lucene.index.IndexReader;import org.apache.lucene.index.IndexWriter;import org.apache.lucene.index.IndexWriterConfig;import org.apache.lucene.index.IndexWriterConfig.OpenMode;import org.apache.lucene.queryParser.MultiFieldQueryParser;import org.apache.lucene.queryParser.QueryParser;import org.apache.lucene.search.Filter;import org.apache.lucene.search.IndexSearcher;import org.apache.lucene.search.Query;import org.apache.lucene.search.ScoreDoc;import org.apache.lucene.search.TopDocs;import org.apache.lucene.store.Directory;import org.apache.lucene.store.FSDirectory;import org.apache.lucene.store.RAMDirectory;import org.apache.lucene.util.Version;/** * 23. * @author xudongwang 2012-2-2 24. * 25. * Email:xdwangiflytek@gmail.com * 26.E:\TestLucene\workspaceSE\indexdocs  */public class FirstLucene {/** * 源檔案路徑 */private String filePath01 = "E:\\TestLucene\\workspaceSE\\L1.txt";private String filePath02 = "E:\\TestLucene\\workspaceSE\\L2.txt";private String filePath03 = "E:\\TestLucene\\workspaceSE\\L3.txt";/** * 索引路徑 */private String indexPath = "E:\\TestLucene\\workspaceSE\\indexdocs";/** * 分詞器,這裡我們使用預設的分詞器,標準分析器(好幾個,但對中文的支援都不好) */private Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_35);private RAMDirectory ramDirectory=null;/** * 建立索引 *  * @throws Exception */public void createIndex() throws Exception {File indexFile = new File(indexPath);Directory directory = FSDirectory.open(indexFile);//寫入器配置需要2個參數,版本,分詞器。還有其他參數,這裡就不再講了。IndexWriterConfig conf = new IndexWriterConfig(Version.LUCENE_35,analyzer);conf.setOpenMode(OpenMode.CREATE);// IndexWriter索引寫入器是用來操作(增、刪、改)索引庫的IndexWriter indexWriter = new IndexWriter(directory, conf);//需要兩個參數,目錄,寫入器配置// 文檔,即要進行索引的單元Document doc01 =File2Document.file2Document(filePath01);Document doc02 =File2Document.file2Document(filePath02);Document doc03 =File2Document.file2Document(filePath03);// 將Document添加到索引庫中indexWriter.addDocument(doc01);indexWriter.addDocument(doc02);indexWriter.addDocument(doc03);indexWriter.close();// 關閉寫入器,釋放資源,索引建立完畢}/** * 建立記憶體索引 *  * @throws Exception *  */public void createRamIndex() throws Exception {File indexFile = new File(indexPath);Directory directory = FSDirectory.open(indexFile);//記憶體索引//RAMDirectory ramDirectory = new RAMDirectory();ramDirectory = new RAMDirectory(directory);//這個帶參數的建構函式把物理索引載入到記憶體。//寫入器配置需要2個參數,版本,分詞器。還有其他參數,這裡就不再講了。IndexWriterConfig ramConf = new IndexWriterConfig(Version.LUCENE_35,analyzer);//ramConf.setOpenMode(OpenMode.CREATE);// IndexWriter索引寫入器是用來操作(增、刪、改)索引庫的IndexWriter ramIndexWriter = new IndexWriter(ramDirectory, ramConf);//需要兩個參數,目錄,寫入器配置// 文檔,即要進行索引的單元Document doc01 =File2Document.file2Document(filePath01);Document doc02 =File2Document.file2Document(filePath02);Document doc03 =File2Document.file2Document(filePath03);// 將Document添加到索引庫中ramIndexWriter.addDocument(doc01);ramIndexWriter.addDocument(doc02);ramIndexWriter.addDocument(doc03);ramIndexWriter.close();// 關閉寫入器,釋放資源,索引建立完畢//把記憶體中的索引與物理的索引合并,起到合并的作用。IndexWriterConfig fsConf = new IndexWriterConfig(Version.LUCENE_35, analyzer);//fsConf.setOpenMode(OpenMode.CREATE_OR_APPEND);IndexWriter fsIndexWriter = new IndexWriter(directory, fsConf);  //把另外幾個索引庫中的所有索引資料合併到當前的索引庫中   fsIndexWriter.addIndexes(ramDirectory);fsIndexWriter.close(); }/** * 搜尋 *  * @param queryStr *            搜尋的關鍵詞 * @throws Exception */public void search(String queryStr) throws Exception {// 1、把要搜尋的文本解析為Query對象// 指定在哪些欄位查詢String[] fields = { "name", "content" };// QueryParser: 是一個解析使用者輸入的工具,可以通過掃描使用者輸入的字串,產生Query對象。QueryParser queryParser = new MultiFieldQueryParser(Version.LUCENE_35,fields, analyzer);// Query:查詢,lucene中支援模糊查詢,語意查詢,短語查詢,組合查詢等等,如有TermQuery,BooleanQuery,RangeQuery,WildcardQuery等一些類。Query query = queryParser.parse(queryStr);// 2、進行查詢File indexFile = new File(indexPath);// IndexSearcher 是用來在索引庫中進行查詢的Directory directory = FSDirectory.open(indexFile);IndexReader indexReader = IndexReader.open(directory);IndexSearcher indexSearcher = new IndexSearcher(indexReader);// Filter 過濾器,我們可以將查出來的結果進行過濾,可以屏蔽掉一些不想給使用者看到的內容Filter filter = null;// 10000表示一次性在資料庫中查詢多少個文檔// topDocs 類似集合TopDocs topDocs = indexSearcher.search(query, filter, 10000);System.out.println("總共有【" + topDocs.totalHits + "】個文檔含有匹配\""+queryStr+"\"的結果");// 注意這裡的匹配結果是指文檔的個數,而不是文檔中包含搜尋結果的個數// 3、列印結果for (ScoreDoc scoreDoc : topDocs.scoreDocs) {int docSn = scoreDoc.doc;// 文檔內部編號Document document = indexSearcher.doc(docSn);// 根據文檔編號取出相應的文檔File2Document.printDocumentInfo(document);// 列印出文檔資訊}}public static void main(String[] args) throws Exception {FirstLucene lucene = new FirstLucene();lucene.createIndex();//建立索引//lucene.createRamIndex();//建立記憶體索引lucene.search("分詞");//搜尋你想找的文字System.out.println("---------------------------");lucene.search("檢索");System.out.println("---------------------------");lucene.search("索引");System.out.println("---------------------------");}}

 

控制台列印:

總共有【3】個文檔含有匹配"分詞"的結果索引name -->L3.txt索引path -->E:\TestLucene\workspaceSE\L3.txt索引size -->619索引name -->L2.txt索引path -->E:\TestLucene\workspaceSE\L2.txt索引size -->561索引name -->L1.txt索引path -->E:\TestLucene\workspaceSE\L1.txt索引size -->1636---------------------------總共有【2】個文檔含有匹配"檢索"的結果索引name -->L1.txt索引path -->E:\TestLucene\workspaceSE\L1.txt索引size -->1636索引name -->L2.txt索引path -->E:\TestLucene\workspaceSE\L2.txt索引size -->561---------------------------總共有【2】個文檔含有匹配"索引"的結果索引name -->L2.txt索引path -->E:\TestLucene\workspaceSE\L2.txt索引size -->561索引name -->L1.txt索引path -->E:\TestLucene\workspaceSE\L1.txt索引size -->1636---------------------------

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.