需求:对多个文档内的数据进行全文检索(文档包括.txt .doc .docx .pdf)
1.对各个文档建立索引
2.对索引进行搜索
各个依赖:
<!-- lucene 核心模块 -->
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
<version>7.3.0</version>
</dependency>
<!-- Lucene提供的中文分词器模块,lucene-analyzers-smartcn:Lucene 的中文分词器 SmartChineseAnalyzer -->
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-analyzers-smartcn</artifactId>
<version>7.3.0</version>
</dependency>
<!-- ikanalyzer 中文分词器 -->
<dependency>
<groupId>com.janeluo</groupId>
<artifactId>ikanalyzer</artifactId>
<version>2012_u6</version>
<!--排除掉里面旧的lucene包,因为我们要重写里面的分析器和分词器 -->
<exclusions>
<exclusion>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-queryparser</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-analyzers-common</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- lucene-queryparser 查询分析器模块 -->
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-queryparser</artifactId>
<version>7.3.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi-scratchpad -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-scratchpad</artifactId>
<version>3.17</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.17</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.pdfbox/pdfbox -->
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>1.8.10</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
建立索引:
/***
* 创建索引
* @param targetFileDir 源文件夹
* @param indexSaveDir 索引存放文件夹
* @throws IOException
*/
public static void indexCreate(File targetFileDir, File indexSaveDir) throws IOException {
// 不是目录或不存在则返回
if (!targetFileDir.isDirectory() || !targetFileDir.exists()) {
return;
}
// 保存Lucene索引文件的路径
Directory directory = FSDirectory.open(indexSaveDir.toPath());
// 创建一个简单的分词器,可以对数据进行分词
Analyzer analyzer = new StandardAnalyzer();
// 创建索引实例
IndexWriterConfig indexWriterConfig = new IndexWriterConfig(analyzer);
IndexWriter indexWriter = new IndexWriter(directory, indexWriterConfig);
// 获取所有需要建立索引的文件
File[] files = targetFileDir.listFiles();
for (int i = 0; i < files.length; i++) {
// 文件的完整路径 files[i].toString()
// 获取文件名称
String fileName = files[i].getName();
// 获取文件后缀名,将其作为文件类型
String fileType = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length()).toLowerCase();
Document doc = new Document();
InputStream in = new FileInputStream(files[i]);
FieldType fieldType = new FieldType();
fieldType.setIndexOptions(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS);
fieldType.setStored(true);
fieldType.setTokenized(true);
if (fileType != null && !fileType.equals("")) {
if (fileType.equals("doc")) {
// 获取doc的word文档
WordExtractor wordExtractor = new WordExtractor(in);
// 创建Field对象,并放入doc对象中
doc.add(new Field("contents", wordExtractor.getText(), fieldType));
// 关闭文档
wordExtractor.close();
} else if (fileType.equals("docx")) {
// 获取docx的word文档
XWPFWordExtractor xwpfWordExtractor = new XWPFWordExtractor( new XWPFDocument(in));
// 创建Field对象,并放入doc对象中
doc.add(new Field("contents", xwpfWordExtractor.getText(), fieldType));
// 关闭文档
xwpfWordExtractor.close();
} else if (fileType.equals("pdf")) {
// 获取pdf文档
PDFParser parser = new PDFParser(in);
parser.parse();
PDDocument pdDocument = parser.getPDDocument();
PDFTextStripper stripper = new PDFTextStripper();
// 创建Field对象,并放入doc对象中
doc.add(new Field("contents", stripper.getText(pdDocument), fieldType));
// 关闭文档
pdDocument.close();
} else if (fileType.equals("txt")) {
String txtFile = FileUtils.readFileToString(files[i]);
// 创建Field对象,并放入doc对象中
doc.add(new Field("contents", txtFile, fieldType));
} else {
System.out.println("文件类型格式错误!!!");
continue;
}
}
// 创建文件名的域,并放入doc对象中
doc.add(new Field("filename", files[i].getName(), fieldType));
// 创建时间的域,并放入doc对象中
doc.add(new Field("indexDate", DateTools.dateToString(new Date(), DateTools.Resolution.DAY), fieldType));
// 写入IndexWriter
indexWriter.addDocument(doc);
}
// 查看IndexWriter里面有多少个索引
System.out.println("查看IndexWriter里面有多少个索引:" + indexWriter.numDocs());
// 关闭索引
indexWriter.close();
}
重复生成索引会造成索引重复
先删除掉索引目录下的所有索引
/**
* 删除指定索引库下面的所有 索引数据
* @param indexDir
*/
public static void indexDelAll(File indexDir) throws IOException {
if (indexDir == null || !indexDir.exists() || indexDir.isFile()) {
return;
}
// 创建 IKAnalyzer 中文分词器
Analyzer analyzer = new IKAnalyzer();
Directory directory = FSDirectory.open(indexDir.toPath());
// 创建 索引写配置对象,传入分词器
IndexWriterConfig config = new IndexWriterConfig(analyzer);
// 创建 索引写对象
IndexWriter indexWriter = new IndexWriter(directory, config);
/** 删除所有索引
* 如果索引库中的索引已经被删除,则重复删除时无效*/
indexWriter.deleteAll();
/** 虽然不 commit,也会生效,但建议做提交操作,*/
indexWriter.commit();
/** 关闭流,里面会自动 flush*/
indexWriter.close();
}