02.全文检索lucene创建索引库
程序员文章站
2022-07-09 12:40:10
...
全文检索lucene创建索引库
一、环境搭建
1). 下载Lucene
2). 核心jar包
jdk版本要求 1.8+
- lucene-analyzers-common-7.4.0.jar
- lucene-core-7.4.0.jar
- commons-io.jar
3). maven依赖
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</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>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
二、步骤
1). 创建索引库
//1. 创建一个Director对象,指定索引库保存的位置。
/* 把索引库保存在内存中 了解即可 实际项目中不需要使用
Directory directory = new RAMDirectory();
*/
// 将索引库保存在磁盘指定的位置
Directory directory = FSDirectory.open(new File("E:\\lucene_repository\\rep_01").toPath());
//2. 基于Directory对象创建一个IndexWriter对象,
/** 使用 IndexWriterConfig 默认配置 (无参构造创建的为 标准的分析器 StandardAnalyzer ) 。
IndexWriter indexWriter = new IndexWriter(directory, new IndexWriterConfig());
*/
// 使用中文的分词器配置创建索引库【还需要安装第三方包和配置文件,详见文章末尾介绍!】
IndexWriterConfig config = new IndexWriterConfig(new IKAnalyzer());
IndexWriter indexWriter = new IndexWriter(directory, config);
//3. 读取磁盘上的文件,对应每个文件创建一个文档对象。
File dir = new File("F:\\03Web开发\\03_lucene\\02.参考资料\\searchsource");
File[] files = dir.listFiles();
for (File file : files) {
// 取文件名
String fileName = file.getName();
// 文件的路径
String filePath = file.getPath();
// 文件的内容
String fileContent = FileUtils.readFileToString(file, "UTF-8");
// 文件的大小
long fileSize = FileUtils.sizeOf(file);
// 创建Field 【lucene包】下的Field对象
/* 参数1:域的名称; 参数2:域的内容; 参数3:是否存储:
域 field 的区别(TextField/StoredField等) 在后面的文章中详解
*/
// fieldName文件名 分析 索引 存储
Field fieldName = new TextField("name", fileName, Field.Store.YES);
// fieldPath文件路径 存储
Field fieldPath = new StoredField("path", filePath);
Field fieldContent = new TextField("content", fileContent, Field.Store.YES);
// fieldSizeValue文件大小值 分析 索引
Field fieldSizeValue = new LongPoint("size", fileSize);
// fieldSizeStore 存储 【size域有两个域属性】
Field fieldSizeStore = new StoredField("size", fileSize + "");
// 创建文档对象
Document document = new Document();
//4. 向文档对象中添加域
document.add(fieldName);
document.add(fieldPath);
document.add(fieldContent);
document.add(fieldSize);
//5. 把文档对象写入索引库
indexWriter.addDocument(document);
}
//6. 关闭indexWriter对象。
indexWriter.close();
使用luck工具可以查看索引库中的信息
2). 查询索引库
//1. 创建一个Director对象,指定索引库的位置
Directory directory = FSDirectory.open(new File("E:\\lucene_repository\\rep_01").toPath());
//2. 创建一个IndexReader对象
IndexReader indexReader = DirectoryReader.open(directory);
//3. 创建一个IndexSearcher对象,构造方法中的参数indexReader对象。
IndexSearcher indexSearcher = new IndexSearcher(indexReader);
//4. 创建一个Query对象,TermQuery, 第一个为域,第二个为查询的内容
Query query = new TermQuery(new Term("content", "spring"));
//5. 执行查询,得到一个TopDocs对象
// 参数1: 查询对象; 参数2:限制查询结果返回的最大记录数,
TopDocs topDocs = indexSearcher.search(query, 10);
//6. 取查询结果的总记录数
System.out.println("查询的总记录数:" + topDocs.totalHits);
//7. 取文档列表
ScoreDoc[] scoreDocs = topDocs.scoreDocs;
//8. 打印文档中的内容
for (ScoreDoc doc : scoreDocs) {
// 取文档id
int docId = doc.doc;
// 根据id获取文档对象
Document document = indexSearcher.doc(docId);
System.out.println(document.get("name"));
System.out.println(document.get("path"));
System.out.println(document.get("size"));
//System.out.println(document.get("content"));
System.out.println("--------------------------------");
}
//9. 关闭IndexReader对象。
indexReader.close();
三、分析器
默认使用为标准分析器 StandardAnalyzer
1). 查看默认分词器的分词效果,就是过滤的最终效果
任何分词器都继承了Analyzer抽象类,使用tokenStream方法返回一个TokenStream对象。词对象中包含了最终分词的结果。
标准分词器分析英文绰绰有余,但是中文,呵呵。。
// 1. 创建一个lucene包下的Analyzer对象,这里使用标准的StandardAnalyzer对象,
Analyzer analyzer = new StandardAnalyzer();
// 2. 使用分词对象的tokenStream方法获得一个TokenStream对象。
// 第一个参数为 fieldName,此案例不需要使用
TokenStream tokenStream = analyzer.tokenStream("", "The Spring Framework provides a comprehensive programming and configuration model.");
// 3. 向TokenStream对象中设置一个引用,相当于一个指针,然后进行分析
CharTermAttribute charTermAttribute = tokenStream.addAttribute(CharTermAttribute.class);
// 4. 调用TokenStream对象的rest方法,重置引用的位置,方便接下来打印输出
tokenStream.reset();
// 5. 使用while循环遍历TokenStream对象
while (tokenStream.incrementToken()) {
System.out.println(charTermAttribute.toString());
}
// 6. 关闭TokenStream对象
tokenStream.close();
2). 中文分词器 IKAnalyze的使用方法
- 把IKAnalyzer的jar包
IK-Analyzer-1.0-SNAPSHOT.jar
添加到工程中;或者将jar包安装到本地maven仓库,或者私服 - 将配置文件和扩展词典添加到工程的classpath下 (resources目录)
-
hotword.dic
: 扩展词典 (格式就是每行一个词语,可以根据业务需求添加,utf-8) -
stopword.dic
: 停用词典 (格式就是每行一个词语,可以根据业务需求添加,utf-8) -
IKAnalyzer.cfg.xml
: 配置文件
-
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>IK Analyzer 扩展配置</comment>
<!--用户可以在这里配置自己的扩展字典,可配置多个 -->
<entry key="ext_dict">hotword.dic;</entry>
<!--用户可以在这里配置自己的扩展停止词字典,可配置多个-->
<entry key="ext_stopwords">stopword.dic;</entry>
</properties>
- 注意:
- 扩展字典严禁使用win的记事本打开编辑,必须得保证编码为utf-8
- 扩展词典可以添加一个新词
- 停用词典:无意义的词或者是敏感词汇
案例演示
Analyzer analyzer = new IKAnalyzer();
TokenStream tokenStream = analyzer.tokenStream("",
"我是一个兵\n来自老百姓\n打败了日本狗强盗\n消灭了蒋匪军\n我是一个兵\n爱国爱人民\n革命战争考验了我\n立场更坚定");
CharTermAttribute charTermAttribute = tokenStream.addAttribute(CharTermAttribute.class);
tokenStream.reset();
while (tokenStream.incrementToken()) {
System.out.println(charTermAttribute.toString());
}
tokenStream.close();
3). 中文分词器 IKAnalyze 的使用方法
代码部分详见 【二、步骤】 -> 【1). 创建索引库】
上一篇: [wp] 攻防世界-web2