lucene_01_入門程序

索引和搜索流程圖:java

 

一、綠色表示索引過程,對要搜索的原始內容進行索引構建一個索引庫,索引過程包括:
肯定原始內容即要搜索的內容->採集文檔->建立文檔->分析文檔->素引文檔
二、紅色表示搜索過程,從索弓庫中搜索內容,
搜索過程包括:
用戶經過搜索界面->建立查詢子執行搜索,從索引庫搜索->渲染搜索結果數據庫

索引和搜索操做的對象爲:索引庫。apache

索引庫中包含的部分:索引、原始文檔。app

原始文檔:要索引和搜索的內容。原始內容包括互聯網上的網頁、數據庫中的數據、磁盤上的文件等。maven

 

建立文檔對象ui

獲取原始內容的目的是爲了索引,在索引前須要將原始內容建立成文檔(Document),
文檔中包括一個一個的域(Field),域中存儲內容。
這裏咱們能夠將磁盤上的-一個文件當成一個document,Document 中包括-一些Field
(file_mame文件名稱、file_path文件路徑、file_size 文件大小、file_content文件內容),以下圖:url

 注意: spa

每一個文檔能夠有多個Field,code

不一樣的文檔能夠有不一樣的Field, —— 對於數據庫辦不到,每一行看做是一個document(文檔),每一列看做是一個Filed.數據庫的每一行的字段是固定的。xml

同一個 文檔能夠有相同的Field (域名和域值都相同)。—— 數據庫中也不能有重複的字段

每一個文檔都有一個惟一的編號,就是文檔id。—— 不一樣數據庫的 id,該id不是域(對應於數據庫的字段),沒法進行操做,由系統維護。

域:是能夠被咱們操做的。

 

分析文檔

將原始內容建立爲包含域(Field) 的文檔(document),須要再對域中的內容進行分析,
分析的過程是通過對原始文檔提取單詞、將字母轉爲小寫、去除標點符號、去除停用詞等過
程生成最終的語彙單元, 能夠將語彙單元理解爲一個一個的單詞。
 
好比下面的文檔通過分析以後。
原文檔內容:
Lucene is a Java full-text search engine.Lucene is not a completer
application,but rather a code library and API that can easily be used
to add search capabilities to applications.

分析後獲得的語彙單元。
lucene、java、full、search、engine。。。
每一個單詞叫作一個Term,不一樣的域中拆分出來的相同的單詞是不一樣的term。
含兩部分一部分是文檔的域名,另外一部分是單詞的內容。。
例如: 文件名中包含apache和文件內容中包含的apache是不一樣的term.
 
建立索引
 
對全部文檔分析得出的語彙單元進行索引,索引的目的是爲了搜索,最終要實現值搜索被索引的語彙單元,從而找到文檔(document)

 

注意: 建立索引是對語彙單元索引,經過詞語找文檔,這種索引的結構叫倒排索引結構
傳統方法是根據文件找到該文件的內容,在文件內容中匹配搜索關鍵字,這種方法是順
序掃描方法,數據量大、搜索慢。

倒排索引結構是經過內容找文檔,以下圖:

 倒排索引結構也叫反向索引結構,包括索引和文檔兩個部分,索引即詞彙表,它的規模較小,而文檔集合較大。

 

入門代碼實現

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.chen</groupId>
  <artifactId>lucene</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>lucene</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.apache.lucene/lucene-core -->
    <dependency>
      <groupId>org.apache.lucene</groupId>
      <artifactId>lucene-core</artifactId>
      <version>7.2.1</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.apache.lucene/lucene-queryparser -->
    <dependency>
      <groupId>org.apache.lucene</groupId>
      <artifactId>lucene-queryparser</artifactId>
      <version>7.2.1</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.2.1</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
    <dependency>
      <groupId>commons-io</groupId>
      <artifactId>commons-io</artifactId>
      <version>2.6</version>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>RELEASE</version>
    </dependency>


  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.6.0</version>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

建立索引

Field類

注在該版本中已經拋棄了LongField方法

  @Test
    public void createIndex() throws Exception{
//        第一步; 建立一個java工程,並導入jar包。
//        第二步: 建立一個indexwriter對象。
//        1) 指定索引庫的存放位置Directory對象

        Directory directory = FSDirectory.open(Paths.get("F:\\lucene\\indexDatabase"));

//        2) 指定一個分聽器,對文檔內容進行分析。
        IndexWriterConfig config = new IndexWriterConfig(new StandardAnalyzer());
        IndexWriter indexWriter = new IndexWriter(directory,config);
//        第四步: 建立field對象,將field添加到document對象中。
        File filedir = new File("F:\\lucene\\document");
        if(filedir.exists() && filedir.isDirectory()){
            File[] files = filedir.listFiles();
            for (File file:files) {
//        第三步,創|建document對象。
                Document document = new Document();
                //獲取文件的名稱
                String fileName = file.getName();
                //建立textfield,保存文件名(key,value,是否存儲)
                TextField fileNameField = new TextField("fileName",fileName, Field.Store.YES);
                //文件大小
                long fileSize = FileUtils.sizeOf(file);
//                new NumericDocValuesField("fileSize",fileSize);
                SortedNumericDocValuesField fileSizeField = new SortedNumericDocValuesField("fileSize", fileSize);
                //文件路徑
                String filePath = file.getPath();
                StoredField filePathField = new StoredField("filePath", filePath);
                //文件內容
                String fileContent = FileUtils.readFileToString(file,"gbk");
                TextField fileContentField = new TextField("fileContent", fileContent, Field.Store.YES);
                document.add(fileNameField);
                document.add(fileSizeField);
                document.add(filePathField);
                document.add(fileContentField);

//        第五步: 使用indexwriter對象將document對象寫入索引庫,此過程進行索引建立。並將索引和document對象寫) 索引庫。
                indexWriter.addDocument(document);
            }
        }
//        第六步: 關閉IndexWriter對象。
        indexWriter.close();

    }

查詢索引

 搜索索引過程:
根據查詢語法在倒排索引詞典表中分別找出對應搜索詞的索引,從而找到索引所連接的文檔鏈表。
好比搜索語法爲「fileName:lucee  表示搜索出fileName 域中包含Lucene 的文檔。
搜索過程就是在索引上查找域爲fileName,而且關鍵字爲Llucene 的term,並根據term 找到文檔id 列表。

 

@Test
    public void testSearcher() throws IOException {
//        第一步: 建立一個Directory 對象,也就是索引庫存放的位置。
        Directory directory = FSDirectory.open(Paths.get("F:\\lucene\\indexDatabase"));
//        第二步: 建立一個indexReader 對象,須要指定Directory 對象。
        IndexReader indexReader = DirectoryReader.open(directory);
//        第三步: 建立一個indexsearcher 對象,須要指定InclexReader 對象。
        IndexSearcher indexSearcher = new IndexSearcher(indexReader);
//        第四步: 建立一個TermQuery對象,指定查詢的域和查詢的關鍵詞。
//        Term term = new Term("fileName", "java");
        Term term = new Term("fileContent", "store");
        Query query = new TermQuery(term);
//        第五步: 執行查詢。
        TopDocs topDocs = indexSearcher.search(query, 13);
//        第六步: 返回查詢結果。遍歷查詢結果並輸出。
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;
        for (ScoreDoc doc : scoreDocs) {
            int docIndex = doc.doc;
            Document document = indexSearcher.doc(docIndex);
            String fileName = document.get("fileName");
            System.out.println(fileName);
            String fileSize = document.get("fileSize");
            System.out.println(fileSize);
            String filePath = document.get("filePath");
            System.out.println(filePath);
            String fileContent = document.get("fileContent");
            System.out.println(fileContent);
            System.out.println("==========================");
        }
//        第七步: 關閉IndexReader 對象。
        indexReader.close();

    }
相關文章
相關標籤/搜索