Lucene全文检索
前言分析:
数据分类:
①结构化数据
格式、长度、类型固定。如数据库中数据。
②非结构化数据
格式、长度、类型不固定。
word文档、pdf文档
数据查询:
①结构化数据查询
sql语言
②非结构化数据查询
1.使用程序读取到内存中,匹配字符串,顺序扫描。(读取速度慢)
2.把非结构化数据变成结构化数据,进行查询。
拆分,提供索引,进行数据查询。
全文检索is what?
创建索引,查询索引的过程叫做全文检索。
创建索引耗时操作,但是
索引可以创建一次,使用多次。
应用场景:
①搜索引擎
百度搜索等
②站内搜索
论坛,博客,新闻
③电商搜索
④等需要搜索地方。
Lucene
Lucene是一个基于java开发的全文检索工具包。
Lucene实现全文检索流程:
1.创建索引
①获得文档:
原始文档:用来作为全文搜索的文档。
搜索引擎:使用爬虫获取原始文档。
站内搜素:数据库中数据。
②构建文档对象:
对应每个原始文档创建一个Documnet对象,每个域名都有唯一id。
每个document对象中包含多个域(field),域中保存就是原始文档数据。
包括:域的名称、域的值
③分析文档:
分词过程。
④创建索引:
基于分词得到的结果创建索引。保存到索引库中。
索引库中包含:
索引
document对象
关键字和文档对应关系
查找文档方式:倒排索引:通过关键字找文档。
2.查询索引
①用户查询接口
② 把关键词封装成一个查询对象。
输入:要查询的域和搜索的关键词。
③执行查询:
根据关键词到对应域上进行搜素。
找到关键词找到对应的文档。
④渲染结果:
根据文档id找到关键词进行高亮,分页等处理。
实现案例:
环境:下载Lucene
工程搭建:
①创建一个java工程
添加jar包:
commons-io-2.6.jar(文件的上传和下载)
lucene-analyzers-common-7.4.0.jar
lucene-core-7.4.0.jar
②步骤:
1.创建 一个Director对象,指定索引库保存的位置。
2.基于Directory对象创建一个IndexWriter对象。
3.读取磁盘文件,为每个文件创建文档对象。
4.向文档对象中添加域
5.把文档对象写入索引库
6.关闭indexWriter对象
③使用luke查看索引库内容
④查询索引库步骤:
1.创建一个Director对象,指定索引库位置。
2.创建一个IndexReader对象
3.创建一个IndexSearcher对象,构造方法中的参数indexeader对象。
4.创建一个Query对象,TermQuery
5.执行查询获得TopDocs对象
6.取查询结果的总记录数
7.取文档列表
8.打印文档中内容
9.关闭IndexReader对象
代码:
用jdk1.9以上。
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.*;
import org.apache.lucene.search.*;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.junit.Test;
import java.io.File;
public class FristLucene {
public static void main(String[] args) throws Exception {
//创建索引
newSuoYin();
//查询索引
selectSuoYin();
}
private static void selectSuoYin() throws Exception{
// 1.创建一个Director对象,指定索引库位置。
Directory directory = FSDirectory.open(new File("D:\\测试文件夹\\索引库").toPath());
// 2.创建一个IndexReader对象
IndexReader indexReader = DirectoryReader.open(directory);
// 3.创建一个IndexSearcher对象,构造方法中的参数indexeader对象。
IndexSearcher indexSearcher = new IndexSearcher(indexReader);
// 4.创建一个Query对象,TermQuery
Query query =new TermQuery(new Term("filename", "apache"));
// 5.执行查询获得TopDocs对象
TopDocs topDocs = indexSearcher.search(query,10);
// 6.取查询结果的总记录数
System.out.println("查询记录条数:"+topDocs.totalHits);
// 7.取文档列表
for (ScoreDoc scoreDoc: topDocs.scoreDocs){
Document document = indexSearcher.doc(scoreDoc.doc);
// 8.打印文档中内容
System.out.println(document.get("filename"));
System.out.println(document.get("path"));
System.out.println(document.get("size"));
System.out.println("---------------");
}
// 9.关闭IndexReader对象
indexReader.close();
}
public static void newSuoYin() throws Exception{
// 1.创建 一个Directory对象,指定索引库保存的位置。
Directory directory = FSDirectory.open(new File("D:\\测试文件夹\\索引库").toPath());
// 2.基于Directory对象创建一个IndexWriter对象。
IndexWriterConfig config = new IndexWriterConfig();
IndexWriter indexWriter = new IndexWriter(directory,config);
// 3.读取磁盘文件,为每个文件创建文档对象。
File file = new File("D:\\资料\\黑马javaee解压\\讲义+笔记\\讲义+笔记+资料\\流行框架\\61.会员版(2.0)-就业课(2.0)-Lucene\\lucene\\02.参考资料\\searchsource");
for(File f : file.listFiles()){
//读取文件
String fileName = f.getName();
String fileContent = FileUtils.readFileToString(f);
String filePath = f.getPath();
long fileSize = FileUtils.sizeOf(f);
// 4.向文档对象中添加域
//第一个参数:域的名称
//第二个参数:域的内容
//第三个参数:是否存储
Field fileNameField = new TextField("filename", fileName, Field.Store.YES);
Field fileContentField = new TextField("content", fileContent, Field.Store.YES);
Field filePathField = new TextField("path", filePath, Field.Store.YES);
Field fileSizeField = new TextField("size", fileSize+"", Field.Store.YES);
//创建document对象
Document document = new Document();
document.add(fileNameField);
document.add(fileContentField);
document.add(filePathField);
document.add(fileSizeField);
// 5.把文档对象写入索引库
indexWriter.addDocument(document);
}
// 6.关闭indexWriter对象
indexWriter.close();
}
}
资源包下载:
Lucene资源包
如果不能查看,请私信我。