Lucene的基本使用-代码总结
原理图
前期准备
创建文件如下 --被查询的内容
使用的jar包
lucene-core-7.4.0.jar lucene-analyzers-common-7.4.0.jar IK-Analyzer-1.0-SNAPSHOT.jar commons-io-2.6.jar lucene-queryparser-7.4.0.jar
配置文件
hotword.dic --存放热门词汇 配合IK-Analyzer分词 stopword.dic --停用词汇 (敏感词) 不参与查询 IKAnalyzer.cfg.xml --IK-Analyzer配置文件
IK-Analyzer.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>入门Demo
创建索引
第一步:创建一个java工程,并导入jar包。
第二步:创建一个indexwriter对象。
1)指定索引库的存放位置Directory对象 2)指定一个IndexWriterConfig对象。
第二步:创建document对象。
第三步:创建field对象,将field添加到document对象中。
第四步:使用indexwriter对象将document对象写入索引库,此过程进行索引创建。并将索引和document对象写入索引库。
第五步:关闭IndexWriter对象。
@Test
public void createIndex() throws Exception{
//1.指定索引库存放的路径
FSDirectory directory = FSDirectory.open(new File("D:\\lucene\\index").toPath());
//2.创建indexWriter对象
IndexWriter indexWriter = new IndexWriter(directory, new IndexWriterConfig());
//3.读取原始文档的路径
File dir = new File("D:\\lucene\\searchsource");
File[] files = dir.listFiles();
for (File file : files) {
//文件名
String fileName = file.getName();
//文件内容
String fileContent = FileUtils.readFileToString(file, "utf-8");
//文件路径
String filePath = file.getPath();
//文件大小
long fileSize = FileUtils.sizeOf(file);
//创建文件名域
//第一个参数:域的名称
//第二个参数:域的内容
//第三个参数:是否存储
Field fileNameField = new TextField("fileName",fileName, Field.Store.YES);
Field fileContentField = new TextField("fileContent",fileContent, Field.Store.YES);
Field filePathField = new TextField("filePath",filePath, Field.Store.YES);
Field fileSizeField = new TextField("fileSize",fileSize+"", Field.Store.YES);
//创建document对象
Document document = new Document();
//文档对象添加域
document.add(fileNameField);
document.add(fileContentField);
document.add(filePathField);
document.add(fileSizeField);
//把文档写入索引库
indexWriter.addDocument(document);
}
//关闭indexWriter
indexWriter.close();
}查询索引
第一步:创建一个Directory对象,也就是索引库存放的位置。
第二步:创建一个indexReader对象,需要指定Directory对象。
第三步:创建一个indexsearcher对象,需要指定IndexReader对象
第四步:创建一个TermQuery对象,指定查询的域和查询的关键词。
第五步:执行查询
第六步:返回查询结果。遍历查询结果并输出。
第七步:关闭IndexReader对象
@Test
public void searchIndex() throws Exception{
//指定索引库存放的路径
FSDirectory directory = FSDirectory.open(new File("D:\\lucene\\index").toPath());
//创建indexReader对象
DirectoryReader indexReader = DirectoryReader.open(directory);
//创建indexSearcher对象
IndexSearcher indexSearcher = new IndexSearcher(indexReader);
//创建查询
Query query = new TermQuery(new Term("fileContent", "spring"));
//执行查询
//第一个参数是查询对象,第二个参数是查询结果返回的最大值
TopDocs topDocs = indexSearcher.search(query, 10);
//查询结果的总条数
System.out.println("查询结果的总条数:" + topDocs.totalHits);
//遍历查询结果啥发送到发送到
//topDocs.scoreDocs存储了document对象的id
for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
//scoreDoc.doc属性接收document对象的id
//根据document的id找到document对象
Document doc = indexSearcher.doc(scoreDoc.doc);
//System.out.println("doc = " + doc.get("fileContent"));
System.out.println("doc = " + doc.get("fileName"));
System.out.println("doc = " + doc.get("filePath"));
System.out.println("doc = " + doc.get("fileSize"));
System.out.println("-----------------------------");
}
//关闭indexReader对象
indexReader.close();
}分析器的使用
这是一个标准分析器
//标准分析器(分词器)
@Test
public void testTokenStream() throws Exception{
//查看标准分析器的分词效果
Analyzer analyzer = new StandardAnalyzer();
//获取tokenStream对象
//第一个参数:域名,可以随便给一个
//第二个参数:要分析的文本内容
TokenStream tokenStream = analyzer.tokenStream("", "The Spring Framework provides a comprehensive programming and configuration model.");
//添加一个引用,可以获得每个关键词
CharTermAttribute charTermAttribute = tokenStream.addAttribute(CharTermAttribute.class);
//将指针调整到列表的头部
tokenStream.reset();
while (tokenStream.incrementToken()){
//其关键词
System.out.println(charTermAttribute.toString());
}
tokenStream.close();
} Lucene自带中文分词器
StandardAnalyzer: 单字分词:就是按照中文一个字一个字地进行分词。如:“任天堂是世界主宰”, 效果:“任”、“天”、“堂”、“是”、“世”、“界””、“主”、“宰”。 SmartChineseAnalyzer 对中文支持较好,但扩展性差,扩展词库,禁用词库和同义词库等不好处理。 这时候就用到了IKAnalyzer
使用IKAnalyzer分词 自制
//IKAnalyzer分析器 测试效果(分词器)
@Test
public void testIKAnalyzerStream() throws Exception{
//查看标准分析器的分词效果
Analyzer analyzer = new IKAnalyzer(); //这里换成IKAnalyzer
//获取tokenStream对象
//第一个参数:域名,可以随便给一个
//第二个参数:要分析的文本内容
TokenStream tokenStream = analyzer.tokenStream("", "小伙子***你结婚了吗");
//添加一个引用,可以获得每个关键词
CharTermAttribute charTermAttribute = tokenStream.addAttribute(CharTermAttribute.class);
//将指针调整到列表的头部
tokenStream.reset();
while (tokenStream.incrementToken()){
//其关键词
System.out.println(charTermAttribute.toString());
}
tokenStream.close();
}索引库的维护
添加
//添加文档
@Test
public void addDocument() throws Exception{
//索引库存放路径
FSDirectory directory = FSDirectory.open(new File("D:\\lucene\\index").toPath());
//创建一个indexWriter对象
IndexWriter indexWriter = new IndexWriter(directory, new IndexWriterConfig(new IKAnalyzer()));
//创建一个Document对象
Document document = new Document();
document.add(new TextField("fileName","新添加的文档",Field.Store.YES));
document.add(new TextField("fileContent","又新添加的文档的内容",Field.Store.NO));
document.add(new StoredField("path","D:\\lucene\\hello"));
indexWriter.addDocument(document);
indexWriter.close();
}删除全部
private IndexWriter indexWriter;
@Before
public void inti() throws Exception{
//创建一个IndexWriter对象,需要使用IKAnalyzer作为分析器
FSDirectory directory = FSDirectory.open(new File("D:\\lucene\\index").toPath());
IndexWriterConfig indexWriterConfig = new IndexWriterConfig(new IKAnalyzer());
indexWriter = new IndexWriter(directory, indexWriterConfig);
}
//删除所有文档
@Test
public void deleteAllDocument() throws Exception{
indexWriter.deleteAll();
indexWriter.close();
}根据查询条件删除索引
private IndexWriter indexWriter;
@Before
public void inti() throws Exception{
//创建一个IndexWriter对象,需要使用IKAnalyzer作为分析器
FSDirectory directory = FSDirectory.open(new File("D:\\lucene\\index").toPath());
IndexWriterConfig indexWriterConfig = new IndexWriterConfig(new IKAnalyzer());
indexWriter = new IndexWriter(directory, indexWriterConfig);
}
//根据查询条件删除索引
@Test
public void deleteIndexByQuery() throws Exception{
indexWriter.deleteDocuments(new Term("fileName","apache"));
indexWriter.close();
}替换修改
private IndexWriter indexWriter;
@Before
public void inti() throws Exception{
//创建一个IndexWriter对象,需要使用IKAnalyzer作为分析器
FSDirectory directory = FSDirectory.open(new File("D:\\lucene\\index").toPath());
IndexWriterConfig indexWriterConfig = new IndexWriterConfig(new IKAnalyzer());
indexWriter = new IndexWriter(directory, indexWriterConfig);
}
//替换查询结果
@Test
public void updateDocument() throws Exception{
//创建一个新的文档对象
Document document = new Document();
//向文档对象中添加域
document.add(new TextField("name1","更新之后的文档1",Field.Store.YES));
document.add(new TextField("name2","更新之后的文档2",Field.Store.YES));
document.add(new TextField("name3","更新之后的文档3",Field.Store.YES));
//更新操作
indexWriter.updateDocument(new Term("fileName","spring"),document);
//关闭文档
indexWriter.close();
}
查询
先抽取循环展示语句
@Before
public void init() throws Exception {
//指定索引库存放的路径 创建indexReader对象
indexReader = DirectoryReader.open(FSDirectory.open(new File("D:\\lucene\\index").toPath()));
//创建indexSearcher对象
indexSearcher = new IndexSearcher(indexReader);
}
//查询的展示语句 抽取出来
private void printResult(Query query) throws IOException {
//执行查询
//第一个参数是查询对象,第二个参数是查询结果返回的最大值
TopDocs topDocs = indexSearcher.search(query, 10);
//查询结果的总条数
System.out.println("查询结果的总条数:" + topDocs.totalHits);
//遍历查询结果啥发送到发送到
//topDocs.scoreDocs存储了document对象的id
for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
//scoreDoc.doc属性接收document对象的id
//根据document的id找到document对象
Document doc = indexSearcher.doc(scoreDoc.doc);
//System.out.println("doc = " + doc.get("fileContent"));
System.out.println("doc = " + doc.get("fileName"));
System.out.println("doc = " + doc.get("filePath"));
System.out.println("doc = " + doc.get("fileSize"));
System.out.println("-----------------------------");
}
}
TermQuery 关键词查询
//TermQuery 关键词查询
@Test
public void searchIndex() throws Exception {
//创建查询
Query query = new TermQuery(new Term("fileName", "spring"));
//调用自己抽取的查询方法
printResult(query);
//关闭indexReader对象
indexReader.close();
}newRangeQuery 范围查询(size)
//newRangeQuery 范围查询(size)
@Test
public void testRangeQuery() throws Exception{
//创建一个query对象
Query query = LongPoint.newRangeQuery("fileSize",0l,1000l);
printResult(query);
//关闭indexReader对象
indexReader.close();
}QueryParser 分词后查询 (先分成词后 再用词查询 类似模糊查询 搜索中比较常用)
@Test
public void testQueryParser() throws Exception{
//创建一个QueryParser对象,两个参数
QueryParser queryParser = new QueryParser("fileName",new IKAnalyzer());
//参数1:默认搜索域,参数2:分析器对象
//使用QueryParser对象创建一盒query对象
Query query = queryParser.parse("lucene是一个Java开发的全文检索工具包");
//执行查询
printResult(query);
}
老板电器公司氛围 197人发布