写在前头
2月初我家这边动车全部停运,假期对于我来说又要加长了,但学习不能终止在家写写博客,是对我学习的一个最好总结。本篇就给大家带来不一样Lucene世界,由于本人水平有限,有不对地方大家麻烦评论区指正。
学习目标
- 何为Lucene
- Lucene理论知识
- 入门使用
- 总结
1.何为Lucene
1.1 我们先去度娘那找,百度百科给我们这样的解释,看完一脸懵逼
只知道它是个工具包,是一套用于全文检索和搜寻的开源程序库。那我们再跑到官网瞧一瞧看一看,因为官网全英文,我用我的工地英语给大家翻译一下哈。
说大白话,就是搞搜索功能的一个工具库。这里肯定大家心中有疑问了,搜索功能不是很简单一个功能吗?我用一条SQL就能搞各种花里胡哨的搜索,它无非就加了算法速度快而已嘛!这里我就不得不给大家科普一下
我们程序员成天跟数据打交道,数据又可以分成两种数据。
1.结构化数据 如数据库那些储存数据
2.非结构化数据 如Word,PDF,视频
当我们要搜索结构化数据我们有SQL,但是非结构化数据要搜索就成一件麻烦的事情,所以Lucene处理这些非结构化数据(非媒体文件,注意Lucene是文本搜索引擎),就是它强大之处,当然也能处理那些结构化数据
2.Lucene理论知识
2.1 其实Lucene可以看做一个数据库,它与众多数据库不同的地方,它维护是索引数据,那么必然少不了对索引CRUD动作,说到这里大家应该明白Lucene是什么东西。
- 原始文件——要索引和搜索的内容。原始内容包括互联网上的网页、数据库中的数据、磁盘上的文件等
- 文档对象(Docment)——这里我们可以将磁盘上的一个文件当成一个document,Document中包括一些Field
- 域(Field)——一个文档对象包含多个域,相当于把一个文档划分多个区域内容
- 分析文档——这个过程就是提词,分词的操作,举个栗子:我是中国人,最后被拆分
1.我
2.中国人
3.中国
4.国人 - 创建索引——对所有文档分析得出的语汇单元进行索引,索引的目的是为了搜索,最终要实现只搜索被索引的语汇单元从而找到Document(文档)
3.入门使用
竟然Lucene是个工具库,我们这里学习它的API即可
3.1 索引库创建,等同create database xxx
// 索引文件保存磁盘
Directory directory = FSDirectory.open(new File("E:\\Downloads\\Temp\\index").toPath());
// 索引文件保存内存
Directory directory = new RAMDirectory();
3.2 这时候需要一个流来处理这些索引文件
// IndexWriterConfig构造可以传入一个分词器对象
IndexWriter indexWriter = new IndexWriter(directory,new IndexWriterConfig());
3.3 insert操作,向索引库添加一个索引
Field fieldName = new TextField("name","你好,我的名字叫张三",Field.Store.YES);
Document document = new Document();
document.add(fieldName);
indexWriter.addDocument(document);
3.4 delete操作,向索引库删除一个索引或全部索引
// 根据内容删除
indexWriter.deleteDocuments(new Term("name","apache"));
// 删除全部
indexWriter.deleteAll();
3.5 update操作,更新一个索引,注意更新操作实质上是先删除后添加
Document document = new Document();
document.add(new TextField("name","aaa",Field.Store.YES));
indexWriter.updateDocument(new Term("name","张三"),document);
3.6 select操作,从索引库查询
// 读取库流
IndexReader indexReader = DirectoryReader.open(directory);
// 查询器
IndexSearcher indexSearcher = new IndexSearcher(indexReader);
// 查询对象
Query query = new TermQuery(new Term("name","张三"));
// 返回对象
TopDocs topDocs = indexSearcher.search(query, 10);
System.out.println("总记录数:" + topDocs.totalHits);
ScoreDoc[] scoreDocs = topDocs.scoreDocs;
for (ScoreDoc scoreDoc : scoreDocs) {
// 获取文档id
int id = scoreDoc.doc;
Document doc = indexSearcher.doc(id);
System.out.println("name:"+doc.get("name"));
System.out.println("====================================");
}
3.7 域的属性
是否分析:是否对域的内容进行分词处理。前提是我们要对域的内容进行查询。
是否索引:将Field分析后的词或整个Field值进行索引,只有索引方可搜索到。
比如:商品名称、商品简介分析后进行索引,订单号、身份证号不用分析但也要索引,这些将来都要作为查询条件。
是否存储:将Field值存储在文档中,存储在文档中的Field才可以从Document中获取
比如:商品名称、订单号,凡是将来要从Document中获取的Field都要存储。
是否存储的标准:是否要将内容展示给用户。
4.总结
4.1 补充一点
还记得3.2中IndexWriterConfig这个对象吗?这里可以传入一个分词器,在Lucene中默认使用标准分词器只能对英文分词,但中文分词需要IK-Analyzer.jar。
4.2 在百度文库已经说明了它不是一个完整全文检索引擎,只是一个工具库,但基于这个库还有很多强大全文检索。所以学习Lucene是学习其他全文检索的基础,学会了Lucene那其他不跟闹着玩一样!
- Apache Solr
- Elasticsearch
到这里本文章对Lucene学习已经结束,当然我会后续再写全文检索文章,祝大家身体健康,技术更上一层楼!!