lucene学习
数据分类
我们生活中的数据总体分为两种:结构化数据和非结构化数据
- 结构化数据: 指具有固定格式或有限长度的数据。
- 非结构化数据: 指不定长或无固定格式的数据。
非结构化数据查询方法
- 顺序扫描法: 从头看到尾,如果此文档包含此字符串,则此文档为我们要找的文件,接着看下一个文件,直到扫描完所有的文件。
- 全文检索: 将非结构化数据中的一部分信息提取出来,重新组织,使其变得有一定结构,然后对此有一定结构的数据进行搜索,从而达到搜索相对较快的目的。这部分从非结构化数据中提出的然后重新组织的信息,我们称之为索引。 这种先建立索引,再对索引进行搜索的过程就叫全文检索。
lucene实现全文检索的流程
-
获取原始文档:原始文档是指要索引和搜索的内容。
-
创建文档对象:获取原始内容的目的是为啦索引,在索引前需要将原始内容创建成文档(Document), 文档中包括一个一个的域,域中存储内容。 每个文档都有一个唯一的编号,就是文档id。
-
分析文档:将原始内容创建为包含域的文档,需要再对域中的内容进行分析。分析出来的每个单元叫做一个term,不同的域中拆分出来 的相同的单词是不同的term。term中包含两部分一部分是文档的域名,另一部分是单词的内容。
-
倒排索引结构:创建索引是对语汇单元索引,通过词语找文档,这种索引的结构叫倒排索引结构。 倒排索引结构也叫反向索引结构,包括索引和文档两部分,索引即词汇表,它的规模较小,而文档集合较大。
-
创建查询: 用户输入查询关键字执行搜索之前需要先构建一个查询对象,查询对象中可以指定查询要搜索的field文档域,查询关键字等,查询对象会生成具体的查询语法, 语法"fileName:lucene"表示要搜索field域的内容为"lucene"的文档。
-
Field域的属性 是否分析, 是否索引, 是否存储
-
创建索引
public void createIndex(){
//指定索引库存放的路径
Directory directory = FSDirectory.open(new File("D:\\temp\\0108\\index"))
//索引库还可以存放到内存中
//Directory directory = new RAMDirectory();
//创建一个标准分析器
Analyzer analyzer = new StandardAnalyzer();
//创建indexConfig对象
//第一个参数:lucene的版本信息,可以选择对应的lucene版本也可以使用latest
//第二个参数:分析器对象
IndexWriterConfig config = new IndexWriterConfig(Version.LATEST,analyzer);
//创建indexwriter对象
IndexWriter indexwriter = new IndexWriter(directory,config);
//原始文档的路径D:\传智播客\01.课程\04.lucene\01.参考资料\searchsource
File dir = new File("D:\\传智播客\\01.课程\\04.lucene\\01.参考资料\\searchsource");
for (File f : dir.listFiles()) {
//文件名
String fileName = f.getName();
//文件内容
String fileContent = FileUtils.readFileToString(f);
//文件路径
String filePath = f.getPath();
//文件的大小
long fileSize = FileUtils.sizeOf(f);
//创建文件名域
//第一个参数:域的名称
//第二个参数:域的内容
//第三个参数:是否存储
Field fileNameField = new TextField("filename", fileName, Store.YES);
//文件内容域
Field fileContentField = new TextField("content", fileContent, Store.YES);
//文件路径域(不分析、不索引、只存储)
Field filePathField = new StoredField("path", filePath);
//文件大小域
Field fileSizeField = new LongField("size", fileSize, 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对象,指定查询的域和查询的关键词。
public void serachIndex(){
//指定索引库存放的路径
Directory directory = FSDirectory.open(new File("D:\\temp\\0108\\index"));
//创建indexReader对象
IndexReader indexReader = DirectoryReader.open(directory);
//创建indexsearcher对象
IndexSearcher indexSearcher = new IndexSearcher(indexReader);
//创建查询
Query query = new TermQuery(new Term("filename","apache"));
//执行查询
//第一个参数是查询对象,第二个参数是查询结果返回的最大值
TopDocs topDocs = indexSearcher.search(query,10);
//遍历查询结果
//topDocs.scoreDocs存储啦document对象的id
for(ScoreDoc scoreDoc : topDocs.scoreDocs){
//根据document的id找到document对象
Document document = indexSearcher.doc(scoreDoc.doc);
}
indexReader.close();
}