Lucene 是 Solr 和 Elasticsearch 的底层基础。打个比方,相当于 JDBC 与 Hibernate、Mybatis之间的关系。
这里就不再过多介绍 Lucene,想了解的可以自行查阅资料。
1、环境配置
我这里是使用 Maven 搭建的 Demo,如果不是的话,需要自己去网上下载相关 jar包。
<!-- Lucene 核心 -->
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
<version>4.10.2</version>
</dependency>
<!-- Lucene 默认分词器 -->
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-analyzers-common</artifactId>
<version>4.10.2</version>
</dependency>
<!-- Lucene 查询解析器 -->
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-queryparser</artifactId>
<version>4.10.2</version>
</dependency>
<!-- Lucene 高亮提示 -->
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-highlighter</artifactId>
<version>4.10.2</version>
</dependency>
<!-- Lucene 索引库优化策略 -->
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-memory</artifactId>
<version>4.10.2</version>
</dependency>
<!-- 中文分词器 -->
<dependency>
<groupId>com.janeluo</groupId>
<artifactId>ikanalyzer</artifactId>
<version>2012_u6</version>
</dependency>
因为 IKAnalyzer 很久没有维护了,最高只能支持 Lucene4.x 的版本。
2、创建索引
具体的创建步骤
- 创建文档
- 创建存储目录
- 创建分词器
- 创建索引写入器配置
- 创建索引写入器
- 将文档交给索引写入器
- 索引写入器提交
- 索引写入器关闭
@Test
public void createIndexDB() throws Exception{
//创建文档,并添加字段
Document document = new Document();
document.add(new StringField("id", "1", Field.Store.YES));
document.add(new TextField("title", "Lucene是apache软件基金会发布的一个开放源代码的全文检索引擎工具包", Field.Store.YES));
//创建存储目录,高版本需要使用 FSDirectory.open(Paths.get("E:\\workspace\\spring-redis\\lucene"))
Directory directory = FSDirectory.open(new File("E:\\workspace\\spring-redis\\lucene"));
//创建中文分词器
Analyzer analyzer = new IKAnalyzer();
//创建索引写入器配置,选择最新版本(Version.LATEST)和中文分词器
IndexWriterConfig config = new IndexWriterConfig(Version.LATEST, analyzer);
//创建索引写入器
IndexWriter indexWriter = new IndexWriter(directory, config);
//清空后再提交
config.setOpenMode(IndexWriterConfig.OpenMode.CREATE);
//在原来的基础上追加新索引
config.setOpenMode(IndexWriterConfig.OpenMode.APPEND);
//添加文档、提交、关闭
indexWriter.addDocument(document);
indexWriter.commit();
indexWriter.close();
}
运行成功后,就可以在存储目录设置的路径中看到索引文件
如果需要提交新的索引,可以设置索引写入配置的打开方式
//清空后再提交
config.setOpenMode(IndexWriterConfig.OpenMode.CREATE);
//在原来的基础上追加新索引
config.setOpenMode(IndexWriterConfig.OpenMode.APPEND);
3、查询索引
具体的查询步骤
- 创建读取目录
- 创建索引读取器
- 创建索引搜索器
- 创建查询解析器
- 创建查询对象
- 搜索数据
- 对数据的相关操作
@Test
public void findIndexDB() throws Exception{
//创建读取目录,高版本需要使用 FSDirectory.open(Paths.get("E:\\workspace\\spring-redis\\lucene"))
Directory directory = FSDirectory.open(new File("E:\\workspace\\spring-redis\\lucene"));
//创建索引读取器
IndexReader reader = DirectoryReader.open(directory);
//创建索引搜索器
IndexSearcher indexSearcher = new IndexSearcher(reader);
//创建查询解析器,这里是对 title 字段查询,分词器选择中文分词器
QueryParser queryParser = new QueryParser("title", new IKAnalyzer());
//通过解析器返回需要查询的对象
Query query = queryParser.parse("软件");
//获取前10条数据,根据匹配度排序
TopDocs topDocs = indexSearcher.search(query, 10);
System.out.println("本次搜索共" + topDocs.totalHits + "条数据");
//根据 ScoreDoc 中的 doc 获取对应的文档 ID
for (ScoreDoc scoreDoc: topDocs.scoreDocs){
int docID = scoreDoc.doc;
Document document = indexSearcher.doc(docID);
String title = document.get("title");
System.out.println(title);
}
}
QueryParser 只能单字段查询,MultiFieldQueryParser 提供多字段查询功能
MultiFieldQueryParser multiFieldQueryParser = new MultiFieldQueryParser(new String[]{"id", "title"}, new IKAnalyzer());
Query query = multiFieldQueryParser.parse("软件");
搜索结果 TopDocs 有两个主要属性
int totalHits 结果总数
ScoreDoc[] scoreDocs 得分文档数组
ScoreDoc 有文档的存储文档的相关信息
int doc 文档 ID (唯一)
float score 文档分数
除了使用解析器,还可以使用词条创建查询对象
Query query = new TermQuery(new Term("title", "软件"));
4、更新、删除索引
更新操作与添加类似,只要创建新的文档,并使用索引写入器更新即可
Document document = new Document();
document.add(new StringField("id", "1", Field.Store.YES));
document.add(new TextField("title", "Lucene是当前以及最近几年最受欢迎的免费Java信息检索程序库", Field.Store.YES));
indexWriter.updateDocument(new Term("id", "1"), document);
indexWriter.commit();
indexWriter.close();
删除操作
//根据词条删除
indexWriter.deleteDocuments(new Term("id", "1"));
//全部删除
indexWriter.deleteAll();
indexWriter.commit();
indexWriter.close();
5、高亮显示
在查询的基础上,增加高亮工具,对关键词进行设置
@Test
public void findIndexDB() throws Exception{
//创建读取目录,高版本需要使用 FSDirectory.open(Paths.get("E:\\workspace\\spring-redis\\lucene"))
Directory directory = FSDirectory.open(new File("E:\\workspace\\spring-redis\\lucene"));
//创建索引读取器
IndexReader reader = DirectoryReader.open(directory);
//创建索引搜索器
IndexSearcher indexSearcher = new IndexSearcher(reader);
//创建查询解析器,这里是对 title 字段查询,分词器选择中文分词器
QueryParser queryParser = new QueryParser("title", new IKAnalyzer());
//通过解析器返回需要查询的对象
Query query = queryParser.parse("软件");
Formatter formatter = new SimpleHTMLFormatter("<span style = 'color: red'>", "</span>");
QueryScorer scorer = new QueryScorer(query);
Highlighter highlighter = new Highlighter(formatter, scorer);
//获取前10条数据,根据匹配度排序
TopDocs topDocs = indexSearcher.search(query, 10);
System.out.println("本次搜索共" + topDocs.totalHits + "条数据");
//根据 ScoreDoc 中的 doc 获取对应的文档 ID
for (ScoreDoc scoreDoc: topDocs.scoreDocs){
int docID = scoreDoc.doc;
Document document = indexSearcher.doc(docID);
String title = document.get("title");
System.out.println(title);
String hTitle = highlighter.getBestFragment(new IKAnalyzer(), "title", title);
System.out.println(hTitle);
}
}
运行完后会看到 “软件” 被 span 标签包裹
本次搜索共1条数据
Lucene是apache软件基金会发布的一个开放源代码的全文检索引擎工具包
Lucene是apache<span style = 'color: red'>软件</span>基金会发布的一个开放源代码的全文检索引擎工具包
发表评论