1. 依赖
1.1 直接下载jar包
Lucene是开发全文检索功能的工具包,从官方网站http://lucene.apache.org/ ,下载lucene-7.4.0,并解压。
Jdk要求:1.8以上
1.2 方式二: pom.xml文件
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
<version>7.4.0</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-queryparser</artifactId>
<version>7.4.0</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-analyzers-common</artifactId>
<version>7.4.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>compile</scope>
</dependency>
2. 需求
实现一个文件的搜索功能,通过关键字搜索文件,凡是文件名或文件内容包括关键字的文件都需要找出来。还可以根据中文词语进行查询,并且需要支持多个条件查询。
本案例中的原始内容就是磁盘上的文件,如下图:
3. 创建索引
3.1 实现步骤
第一步:创建一个java工程,并导入jar包。
第二步:创建一个indexwriter对象。
- 指定索引库的存放位置Directory对象
- 指定一个IndexWriterConfig对象。
第二步:创建document对象。
第三步:创建field对象,将field添加到document对象中。
第四步:使用indexwriter对象将document对象写入索引库,此过程进行索引创建。并将索引和document对象写入索引库。
第五步:关闭IndexWriter对象。
3.2 代码
import org.apache.commons.io.FileUtils;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.*;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.junit.Test;
import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
/**
* 创建索引
*/
public class TestCreateIndex {
@Test
public void testCreateIndex() throws IOException {
//1.创建Directory对象,指定索引库的存放位置
//存放到磁盘中
Directory directory = FSDirectory.open(Paths.get("D:\\test\\lucene\\programme"));
//存放到内存中
//Directory directory = new RAMDirectory();
//2.指定一个标准分析器,对文档内容进行分析
Analyzer analyzer = new StandardAnalyzer();
//3.基于分析器创建 IndexWriterConfig 对象
IndexWriterConfig config = new IndexWriterConfig(analyzer);
//4.创建一个 IndexWriter 对象
IndexWriter indexWriter = new IndexWriter(directory, config);
//5.读取磁盘上的文件,对应每个文件创建一个文档对象
File dir = new File("D:\\test\\lucene\\searchsource");
for (File f : dir.listFiles()) {
//文件名
String fileName = f.getName();
//文件内容
String fileContent = FileUtils.readFileToString(f);
//文件路径
String filePath = f.getPath();
//文件的大小
long fileSize = FileUtils.sizeOf(f);
//6.创建文件名域
//第一个参数:域的名称
//第二个参数:域的内容
//第三个参数:是否存储
Field fileNameField = new TextField("filename", fileName, Field.Store.YES);
//文件内容域
Field fileContentField = new TextField("content", fileContent, Field.Store.YES);
//文件路径域(不分析、不索引、只存储)
Field filePathField = new TextField("path", filePath, Field.Store.YES);
//文件大小域
Field fileSizeField = new TextField("size", fileSize + "", Field.Store.YES);
//7.创建document对象,并将域添加到文档对象中
Document document = new Document();
document.add(fileNameField);
document.add(fileContentField);
document.add(filePathField);
document.add(fileSizeField);
//8.把文档对象写入索引库
indexWriter.addDocument(document);
}
//9.关闭indexwriter
indexWriter.close();
}
}
3.3 运行结果
3.4 使用Luke工具查看索引文件
luke-javafx-7.4.0-luke-release.zip
我们使用的luke的版本是luke-7.4.0,跟lucene的版本对应的。可以打开7.4.0版本的lucene创建的索引库。需要注意的是此版本的Luke是jdk9编译的,所以要想运行此工具还需要jdk9才可以。
4. 查询索引
4.1 步骤
第一步:创建一个Directory对象,也就是索引库存放的位置。
第二步:创建一个indexReader对象,需要指定Directory对象。
第三步:创建一个indexsearcher对象,需要指定IndexReader对象
第四步:创建一个TermQuery对象,指定查询的域和查询的关键词。
第五步:执行查询。
第六步:返回查询结果。遍历查询结果并输出。
第七步:关闭IndexReader对象
4.2 代码
import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.*;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.junit.Test;
import java.nio.file.Paths;
/**
* 查询索引
*/
public class TestSearchIndex {
@Test
public void testSearchIndex() throws Exception {
//1. 指定索引库存放的路径
Directory directory = FSDirectory.open(Paths.get("D:\\test\\lucene\\programme"));
//2. 创建indexReader对象
IndexReader indexReader = DirectoryReader.open(directory);
//3. 创建indexsearcher对象
IndexSearcher indexSearcher = new IndexSearcher(indexReader);
//4. 创建查询
Query query = new TermQuery(new Term("filename", "apache"));
//5. 执行查询
//第一个参数是查询对象,第二个参数是查询结果返回的最大值
TopDocs topDocs = indexSearcher.search(query, 10);
//查询结果的总条数
System.out.println("查询结果的总条数:"+ topDocs.totalHits);
//6. 遍历查询结果
//topDocs.scoreDocs存储了document对象的id
for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
//scoreDoc.doc属性就是document对象的id
//根据document的id找到document对象
Document document = indexSearcher.doc(scoreDoc.doc);
System.out.println(document.get("filename"));
//System.out.println(document.get("content"));
System.out.println(document.get("path"));
System.out.println(document.get("size"));
System.out.println("-------------------------");
}
//7. 关闭indexreader对象
indexReader.close();
}
}