索引和搜索流程圖: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不是域(對應於數據庫的字段),沒法進行操做,由系統維護。
域:是能夠被咱們操做的。
分析文檔
注意: 建立索引是對語彙單元索引,經過詞語找文檔,這種索引的結構叫倒排索引結構。
傳統方法是根據文件找到該文件的內容,在文件內容中匹配搜索關鍵字,這種方法是順
序掃描方法,數據量大、搜索慢。
倒排索引結構是經過內容找文檔,以下圖:
倒排索引結構也叫反向索引結構,包括索引和文檔兩個部分,索引即詞彙表,它的規模較小,而文檔集合較大。
入門代碼實現
<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(); }
查詢索引
@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(); }