创建索引
1.获得原始文档,就是 含有内容的 word txt 等非结构化数据 (读入内存)
2.创建文档对象 Document 就是含有多个域 的对象 域中存储 文档的信息 包括存储路径 ,文档名称 文档大小 文档内容
注意:每个Document可以有多个Field,不同的Document可以有不同的Field,同一个Document可以有相同的Field(域名和域 值都相同)每个文档都有一个唯一的编号,就是文档id
3.分析文档将文档结构化
将原始内容创建为包含域(Field)的文档(document),需要再对域中的内容进行分析,分析的过程是 经过对原始文档提取 单词、将字母转为小写、去除标点符号、去除停用词等过程生成最终的语汇单元,可以将语汇单元理解为一个一个的单词。
每个单词叫做一个Term,不同的域中拆分出来的相同的单词是不同的term
4.创建索引 创建索引是对语汇单元索引,通过词语找文档(id),这种索引的结构叫倒排索引结构。
环境
commons-io-2.6.jar
lucene-analyzers-common-7.4.0.jar
lucene-core-7.4.0.jar
1.创建索引 使用标准 索引库 StandardAnalyzer()
@Test
public void createIndex() throws Exception{
//1、创建一个Director对象,指定索引库保存的位置。
//把索引库保存在内存中
//Directory directory = new RAMDirectory();
//把索引库保存在磁盘
Directory directory = FSDirectory.open(new File("D:\\java\\Java源码\\Lucene\\indexlib").toPath());
//2、基于Directory对象创建一个IndexWriter对象
IndexWriterConfig config = new IndexWriterConfig(new StandardAnalyzer());
IndexWriter indexWriter = new IndexWriter(directory, config);
//3、读取磁盘上的文件,对应每个文件创建一个文档对象。
File dir = new File("D:\\java\\Java源码\\Lucene\\searchsource");
File[] files = dir.listFiles();
for (File f :
files) {
//取文件名
String fileName = f.getName();
//文件的路径
String filePath = f.getPath();
//文件的内容
String fileContent = FileUtils.readFileToString(f, "utf-8");
//文件的大小
long fileSize = FileUtils.sizeOf(f);
//创建Field
参数1:域的名称,参数2:域的内容,参数3:是否存储
Field fieldName = new TextField("name", fileName, Field.Store.YES);
//Field fieldPath = new TextField("path", filePath, Field.Store.YES);
Field fieldPath = new StoredField("path", filePath);
Field fieldContent = new TextField("content", fileContent, Field.Store.YES);
//Field fieldSize = new TextField("size", fileSize + "", Field.Store.YES);
Field fieldSizeValue = new LongPoint("size", fileSize);
Field fieldSizeStore = new StoredField("size", fileSize);
//创建文档对象
Document document = new Document();
//向文档对象中添加域
document.add(fieldName);
document.add(fieldPath);
document.add(fieldContent);
//document.add(fieldSize);
document.add(fieldSizeValue);
document.add(fieldSizeStore);
//5、把文档对象写入索引库
indexWriter.addDocument(document);
}
//6、关闭indexwriter对象
indexWriter.close();
2.查询索引
@Test
public void searchIndex() throws Exception {
//1、创建一个Director对象,指定索引库的位置
Directory directory = FSDirectory.open(new File("D:\\java\\Java源码\\Lucene\\indexlib").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();
}
查看分词效果
1.Analyzer 所有分词标准的接口 StandardAnalyzer 标准分词规则 创建Analyzer 对象
2.使用Analyzer 对象 获得TokenStream对象 ,相当于分析后的一个结构
3.往TokenStream对象中添加一个 指针 使用 reset() 将指针移到开头
4.遍历tokenStream incrementToken()判断指针下一位 是否还有单词
@Test
public void testTokenStream() throws Exception {
//1)创建一个Analyzer对象,StandardAnalyzer对象
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对象的rest方法。如果不调用抛异常
tokenStream.reset();
//5)使用while循环遍历TokenStream对象
while(tokenStream.incrementToken()) {
System.out.println(charTermAttribute.toString());
}
//6)关闭TokenStream对象
tokenStream.close();
}}
Lucene 中文分词
1. 需要 第三方jar包
IK-Analyzer-1.0-SNAPSHOT.jar
2. 可以自定义 停用词 分词库 必须使用utf-8编码
停用词 stopword.dic 列如 公安局这个词语 不想 分析出来 就在 停用词文件中加入即可
分词库 hotword.dic 列如不是一些单词的: 网络词语 就在 分词库文件中加入即可
3.IKAnalyzer.cfg.xml 这三个 配置文件 名称固定 需要放在classpath路径下
<?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>
只需将StandardAnalyzer () 换为 IKAnalyzer() 即可创建 可以分析中文的 索引库