Lucene搜索引擎入門


一.什么是全文檢索?
            就是在檢索數據,數據的分類:
                在計算機當中,比如說存在磁盤的文本文檔,HTML頁面,Word文檔等等......
            1.結構化數據
                格式固定,長度固定,數據類型固定等等,我們稱之為結構化數據,比如說數據庫中的數據

            2.非結構化數據
                word文檔,HTML文件,pdf文檔,文本文檔等等,格式不固定,長度不固定,數據類型不固定,成為非結構化數據
            
            3.半結構化數據

二.數據的查詢
            1.結構化數據查詢
                結構化數據查詢語言:SQL語句       select * from user where userid=1
            2.非結構化數據的查詢
                非結構化數據查詢有一些難度,比如我們在一個文本文件當中找到spring關鍵字
                1.目測       一個一個查找文件....
                2.使用程序將文件讀取到內存當中,然后匹配字符串spring,這種方式被稱為順序掃描
                3.將我們非結構化數據轉換為結構化數據
                    例如Spring.txt文件中,英文文件每一個單詞都是以空格進行區分,那么我們可以采用空格進行分割
                    然后將分割結果保存到數據庫,這樣就形成了一張表,我們在列上創建索引,加快查詢速度,根據單詞和文檔
                    的對應關系找到文檔列表,這樣的過程我們稱之為全文檢索
        

三.全文檢索概念
            創建索引,然后查詢索引的過程我們稱之為全文檢索,索引一次創建可以多次使用,這樣就不用了每一次都進行文件數據拆分,比較快
    

四.全文檢索應用場景
            1.搜索引擎
                百度,360,谷歌等等
            2.站內搜索
                論壇搜索帖子,微博搜索熱點,新聞網站搜索新聞
            3.電商搜索
                淘寶,京東
            有搜索的地方都可以用到全文檢索
    
    
    
五.全文檢索框架Lucene
            Lucene:apache Lucene基於Java開發開源全文檢索項目工具包,http://lucene.apache.org/,除Lucene外,Solr,ES等都是全文檢索框架,以及Lucene
            Lucene全文檢索流程:
                1.創建索引
                    1.1 獲取文檔
                        獲得原始文檔,要基於那些數據進行搜索,這些數據就是原始文檔
                
                        如何獲取原始文檔:
                            1.搜索引擎:根據爬蟲獲得原始文檔
                            2.站內搜索:基本上都是從數據庫當中獲取的,JDBC獲取
                            3.磁盤文件:利用IO流讀取
                    1.2 構建文檔對象
                        每一個原始文檔都是一個文檔對象,比如磁盤文件,每一個文件就是一個文檔對象,京東搜索,每一個商品就是一個文檔對象
                        每一個文檔對象當中包含多個域,域中存儲文檔信息,存儲文檔名稱,文檔路徑,文檔大小,文檔內容,域中有兩大部分:
                        域的名稱name,域的值spring.txt  key=value,每一個文檔都有一個文檔編號ID
                    1.3 分析文檔(分詞)
                        1.3.1 根據空格進行字符串拆分,得到單詞列表
                        1.3.2 單詞統一轉換為小寫或者大寫,用戶查詢時,將查詢內容也統一轉換為大寫或者小寫
                        1.3.3 去掉標點
                        1.3.4 去除停用詞(文檔數據當中無意義的詞,比如  the   a   )
                        1.3.5 得到分詞結果之后,每一個關鍵詞都封裝成一個term對象,term對象包含兩大部分:
                            1.關鍵詞所在的域
                            2.關鍵詞本身
                            不同的域拆分出來相同的關鍵詞是不同的term,比如從文件名和文件內容都拆分出來spring關鍵詞,這兩個spring是完全不同域的
                    1.4 創建索引
                        基於關鍵詞列表創建一個索引,保存到索引庫當中,一次創建多次使用
                        索引庫:
                            1.索引
                            2.document對象
                            3.關鍵詞和文檔的對應關系,采用倒排索引結構
                            spring
                2.查詢索引
                    2.1 用戶查詢接口:用戶輸入查詢條件的地方,比如百度搜索框,jd商品搜索框
                    2.2 獲取到關鍵詞,獲取到關鍵詞后封裝成一個查詢對象
                        要查詢的域,和要搜索的關鍵詞
                    2.3 執行查詢,根據查詢的關鍵詞和對應的域去查詢
                    2.4 根據關鍵詞和文檔的對應關系,利用倒排索引結構,找到文檔id,找到id后就能定位到文檔
                    2.5 渲染結果

 

六.Lucene入門程序案例

環境搭建,創建一個maven工程,導入依賴

<!-- https://mvnrepository.com/artifact/org.apache.lucene/lucene-core -->
            <dependency>
              <groupId>org.apache.lucene</groupId>
              <artifactId>lucene-core</artifactId>
              <version>7.4.0</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.apache.lucene/lucene-analyzers-common -->
            <dependency>
              <groupId>org.apache.lucene</groupId>
              <artifactId>lucene-analyzers-common</artifactId>
              <version>7.4.0</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
            <dependency>
              <groupId>commons-io</groupId>
              <artifactId>commons-io</artifactId>
              <version>2.4</version>
            </dependency>

1. 創建索引

public static void main(String[] args) throws IOException {
        //步驟一:創建Directory對象,用於指定索引庫的位置    RAMDirectory內存
        Directory directory = FSDirectory.open(new File("E:\\Y2學習\\Lucene\\索引庫\\Index").toPath());
        //步驟二:創建一個IndexWriter對象,用於寫索引
        IndexWriter indexWriter=new IndexWriter(directory,new IndexWriterConfig());
        //步驟三:讀取磁盤中文件,對應每一個文件創建一個文檔對象
        File file=new File("E:\\Y2學習\\Lucene\\資料\\資料\\資料\\searchsource");
        //步驟四:獲取文件列表
        File[] files = file.listFiles();
        for (File item:files) {
            //步驟五:獲取文件數據,封裝域   參數三:是否存儲
            Field fieldName=new TextField("fieldName",item.getName(), Field.Store.YES);
            Field fieldPath=new TextField("fieldPath",item.getPath(), Field.Store.YES);
            Field fieldSize=new TextField("fieldSize", FileUtils.sizeOf(item)+"", Field.Store.YES);
            Field fieldContent=new TextField("fieldContent", FileUtils.readFileToString(item,"UTF-8"), Field.Store.YES);
            //步驟六:創建文檔對象,向文檔對象中添加域
            Document document=new Document();
            document.add(fieldName);
            document.add(fieldPath);
            document.add(fieldSize);
            document.add(fieldContent);

            //步驟七:創建索引,將文檔對象寫入到索引庫
            indexWriter.addDocument(document);
        }
        //步驟八:關閉資源
        indexWriter.close();
    }

啟動main方法后,索引庫多了如下二進制文件

 

 

 

2. 利用Luke工具查看索引庫內容
     2.1 指定索引庫位置

 

2.2 查看當前索引庫內容

 選擇完路徑點擊OK,就可根據需求查找索引

 

 

 

 

3. 查看索引

public static void main(String[] args) throws IOException {
        //1.創建Directory對象,指定索引庫位置
        Directory directory = FSDirectory.open(new File("E:\\Y2學習\\Lucene\\索引庫\\Index").toPath());
        //2.創建IndexReader對象,讀取索引庫內容
        IndexReader indexReader= DirectoryReader.open(directory);
        //3.創建IndexSearcher對象
        IndexSearcher indexSearcher=new IndexSearcher(indexReader);
        //4.創建Query查詢對象
        Query query=new TermQuery(new Term("fieldContent","spring"));
        //5.執行查詢,獲取到文檔對象
        TopDocs topDocs = indexSearcher.search(query, 10);
        System.out.println("共獲取:"+topDocs.totalHits+"個文檔~~~~~~~~~~~~~~~~~~~~~");
        //6.獲取文檔列表
        ScoreDoc[] scoreDocs=topDocs.scoreDocs;
        for (ScoreDoc item:scoreDocs) {
            //獲取文檔ID
            int docId=item.doc;
            //取出文檔
            Document doc = indexSearcher.doc(docId);
            //獲取到文檔域中數據
            System.out.println("fieldName:"+doc.get("fieldName"));
            System.out.println("fieldPath:"+doc.get("fieldPath"));
            System.out.println("fieldSize:"+doc.get("fieldSize"));
            System.out.println("fieldContent:"+doc.get("fieldContent"));
            System.out.println("==============================================================");
        }
        //7.關閉資源
        indexReader.close();
    }

執行效果:

 

 

 

 

 

 


   

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM