工程搭建
-
创建一个Java工程
-
添加jar包:
-
lucene-analyzers-common-xxx.jar
-
lucene-core-xxx.jar
-
commons-io.jar
-
-
目录树
创建索引库步骤
- 创建一个Director对象,指定索引库保存的位置
- 基于Director对象创建一个IndexWriter对象
- 读取磁盘上的文件,对应每个文件来创建一个文档对象
- 向文档对象中添加域
- 将文档对象写入索引库
- 关闭IndexWriter对象
代码:
package com.itheima.lucene;
import java.io.File;
import org.apache.commons.io.FileUtils;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
// 建立索引库
public class LuceneFirst {
public static void main(String[] args) throws Exception {
createIndex();
}
public static void createIndex() throws Exception{
// 1.创建一个Director对象,指定索引库保存的位置
// - 将索引库保存在内存中 这样的话会导致索引库在程序运行结束后自动释放。
// Directory directory = new RAMDirectory();
// - 将索引库保存在硬盘上。
Directory directory = FSDirectory.open(new File("E:\\syk").toPath());
// 2.基于Director对象创建一个IndexWriter对象
// - 创建一个IndexWriter对象需要两个参数,第一个是Director对象,第二个是相关的规则配置
IndexWriter indexwriter = new IndexWriter(directory, new IndexWriterConfig());
// 3.读取磁盘上的文件,对应每个文件来创建一个文档对象
// - 创建一个文档对象指向需要建立索引库的文件目录
File dir = new File("E:\\searchsource");
// - 得到目录下的文件列表
File[] files = dir.listFiles();
// - 遍历文件列表
for(File f : files){
// - 获取文件名
String fileName = f.getName();
System.out.println("文件名:" + fileName);
// - 获取文件路径
String filePath = f.getPath();
System.out.println("文件路径:" + filePath);
// - 获取文件内容
String fileContent = FileUtils.readFileToString(f, "utf-8");
System.out.println("文件内容:" + fileContent);
// - 文件大小
long fileSize = FileUtils.sizeOf(f);
System.out.println("文件大小:" + fileSize);
// - 创建Field 参数1:域的名称;参数2:域的内容;参数3:是否存储
Field fieldName = new TextField("name",fileName,Field.Store.YES);
System.out.println("FieldName:" + fieldName);
Field fieldPath = new TextField("Path",filePath,Field.Store.YES);
System.out.println("FieldPath:" + fieldPath);
Field fieldContent = new TextField("Content",fileContent,Field.Store.YES);
System.out.println("FieldContent:" + fieldContent);
Field fieldSize = new TextField("Size",fileSize+"",Field.Store.YES);
System.out.println("FieldSize:" + fieldSize);
// - 创建文档对象
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();
}
}
查询索引库步骤
-
创建一个Director对象,指定索引库保存的位置
-
基于Director对象创建一个IndexReader对象
-
创建一个IndexSearcher对象,构造方法中的参数IndexReader对象
-
创建一个Query对象,TermQuery
-
执行查询,得到一个TopDocs对象
-
取查询结果的总记录数
-
获取文档列表
-
打印文档中的内容
-
关闭IndexReader对象
代码:
package com.itheima.lucene;
import java.io.File;
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.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
public class LuceneSearch {
public static void main(final String[] args) throws Exception{
searchIndex();
}
public static void searchIndex() throws Exception{
// 1.创建一个Director对象,指定索引库保存的位置
Directory directory = FSDirectory.open(new File("E:\\syk").toPath());
// 2.基于Director对象创建一个IndexReader对象
IndexReader indexReader = DirectoryReader.open(directory);
// 3.创建一个IndexSearcher对象,构造方法中的参数IndexReader对象
IndexSearcher indexSearcher = new IndexSearcher(indexReader);
// 4.创建一个Query对象,TermQuery 参数1:查询范围(选择查询文档内容);参数2:查询文本
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"));
}
// 9.关闭IndexReader对象
indexReader.close();
}
}
标准分析器(StandarAnalyzer)
- 创建一个StandarAnalyzer对象
- 使用分析器对象的tokenStream方法获得一个TokenStream对象
- 向TokenStream对象中设置一个引用,相当于是一个指针
- 调用TokenStream对象的reset方法,如果不调用,会抛异常
- 使用while循环遍历TokenStream对象
- 关闭TokenStream
代码:
package com.itheima.lucene;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
public class LuceneAnalyzer {
public static void main(String[] args) throws Exception {
tokenStream();
}
public static void tokenStream() throws Exception{
// 1.创建一个StandarAnalyzer对象
Analyzer analyzer = new StandardAnalyzer();
// 2.使用分析器对象的tokenStream方法获得一个TokenStream对象
TokenStream tokenStream = analyzer.tokenStream("", "The Spring Framework provides a comprehensive programming and configuration model.");
// 3.向TokenStream对象中设置一个引用,相当于是一个指针
CharTermAttribute charTermAttribute = tokenStream.addAttribute(CharTermAttribute.class);
// 4.调用TokenStream对象的reset方法,如果不调用,会抛异常
tokenStream.reset();
// 5.使用while循环遍历TokenStream对象
while(tokenStream.incrementToken()){
System.out.println(charTermAttribute.toString());
}
// 6.关闭TokenStream
tokenStream.close();
}
}
中文分析器
将IKAnalyzer.jar导入,这个jar包用于对中文进行分词分析。
将配置文件与词典放到项目中classpath目录下。
词典不允许使用Windows记事本编辑。
词典分为两个,分别是hotword.dic和stopword.dic。前者是扩展词典,我们可以向其内部添加用于分词的新词汇;后者是停用词典,用于屏蔽无意义词汇与敏感词汇。
package com.itheima.lucene;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.wltea.analyzer.lucene.IKAnalyzer;
public class LuceneIKAnalyzer {
public static void main(String[] args) throws Exception {
tokenStream();
}
public static void tokenStream() throws Exception{
// 1.创建一个IKAnalyzer对象
IKAnalyzer analyzer = new IKAnalyzer();
// 2.使用分析器对象的tokenStream方法获得一个TokenStream对象
TokenStream tokenStream = analyzer.tokenStream("", "实现利润最大化,利润最终来源于赚取每种商品尽可能多的差价,降低获得产品的开销,提供具有较强竞争力的环境以吸引更多的顾客消费。");
// 3.向TokenStream对象中设置一个引用,相当于是一个指针
CharTermAttribute charTermAttribute = tokenStream.addAttribute(CharTermAttribute.class);
// 4.调用TokenStream对象的reset方法,如果不调用,会抛异常
tokenStream.reset();
// 5.使用while循环遍历TokenStream对象
while(tokenStream.incrementToken()){
System.out.println(charTermAttribute.toString());
}
// 6.关闭TokenStream
tokenStream.close();
analyzer.close();
}
}
运行结果:
实现
利润
最大化
最大
大化
利润
最终
来源于
来源
源于
赚取
每种
商品
尽可能
尽可
可能
多
的
差价
降低
获得
产品
的
开销
提供
具有
有
较强
竞争力
竞争
力
的
环境
以
吸引
更多
的
顾客
消费
现在我们在扩展词典中添加:实现利润最大化;在停用词典中添加竞争力。
运行结果:
实现利润最大化
实现
利润
最大化
最大
大化
利润
最终
来源于
来源
源于
赚取
每种
商品
尽可能
尽可
可能
多
的
差价
降低
获得
产品
的
开销
提供
具有
有
较强
竞争
力
的
环境
以
吸引
更多
的
顾客
消费
想要在程序中使用分析器只需要修改一个地方:
IndexWriter indexwriter = new IndexWriter(directory, new IndexWriterConfig(new IKAnalyzer()));