一、Lucene的介绍
Lucene是一个全文检索的框架,apache组织提供了一个用Java实现的全文搜索引擎的开源项目,其功能非常的强大,api非常简单,并且有了全文检索的功能支持可以非常方便的实现根据关键字来搜索整个应用系统的内容,大大提高了用户的体验效果。 使用Lucene来建立、搜索功能和操作数据库有一点像,这样就可想而知,Lucene使用起来还是蛮方便的。
那么为什么要使用Lucene 呢? 因为如果没有使用Lucene ,那么就要根据某个关键字来搜索数据库表记录, 就要使用like 一个字符一个字符去匹配,这样子查询的方式的要累坏程序员不说,并且查询数据库的性能开销可想而知。
二、Lucene的执行流程
前面说了Lucene的操作方式和操作数据库有点相似,所以如果要使用Lucene 就要先创建“数据库”,然后往这个“数据表”中一行一行的插入数据,数据插入成功之后,就可以操作这张“数据表”,实现增删改查操作了。
总的来说,可以这样理解:
1、创建一个索引文件目录,然后把需要检索的信息 用Field 对应匹配的 封装成一个Document文档对象,将这个对象放入索引文件目录中,这里既可以将索引存放到磁盘中,也可以放入内存中,如果放入内存,那么程序关闭索引就没有了,所以一般都是将索引放入磁盘中;
2、如果发现信息有问题需要删除,那么索引文件也要删除,否则检索的时候还是会查询得到,这个时候需要根据索引id去删除对应的索引;
3、如果发现信息被更新了,那么索引文件也要更新,这个时候需要先将旧的索引删除然后添加新的索引;
4、最后重头戏是全文搜索了,这和查询数据库一样,先需要创建索引读取对象,然后封装Query查询对象,调用search()方法 得到检索结果。
三、使用Lucene的准备条件
lucene-analyzers-common-5.4.0.jar lucene-core-5.4.0.jar
lucene-highlighter-5.4.0.jar
lucene-memory-5.4.0.jar
lucene-queryparser-5.4.0.jar
lucene 5.4.0.zip下载地址:https://pan.baidu.com/s/1pL7vL4v
四、使用Lucene实战
1、使用Lucene将索引 写入文件/磁盘
实现的思路如下:
<1>创建了文件/磁盘目录对象Directory 和 索引写入器IndexWriter ;
<2>利用索引写入器将指定的数据存入文件/磁盘目录对象中;
<3>关闭IndexWriter 写入器,关闭Directory目录对象。
public void CreateIndex() throws Exception{
/**
* 1、创建一个article对象,并且把信息存放进去
* 2、调用indexWriter的API把数据存放在索引库中
* 3、关闭indexWriter
*/
//创建一个article对象,并且把信息存放进去
Article article = new Article();
article.setId(1L);
article.setTitle("lucene可以做搜索引擎");
article.setContent("baidu,google都是很好的搜索引擎");
//调用indexWriter的API把数据存放在索引库中
/**
* 创建一个IndexWriter
* 参数三个
* 1、索引库 指向索引库的位置
* 2、分词器
*/
//创建索引库
File file = new File("D:\\indexDir");
Directory directory = FSDirectory.open(file.toPath());
//创建分词器
Analyzer analyzer = new StandardAnalyzer();
IndexWriterConfig config = new IndexWriterConfig(analyzer);
config.setOpenMode(IndexWriterConfig.OpenMode.CREATE_OR_APPEND);
IndexWriter indexWriter = new IndexWriter(directory, config);
//IndexWriter indexWriter = new IndexWriter(directory, analyzer, MaxFieldLength.LIMITED);
//把一个article对象转化成document
Document document = new Document();
Field idField = new Field("id",article.getId().toString(),Store.YES,Index.NOT_ANALYZED);
Field titleField = new Field("title",article.getTitle(),Store.YES,Index.ANALYZED);
Field contentField = new Field("content",article.getContent(),Store.YES,Index.ANALYZED);
document.add(idField);
document.add(titleField);
document.add(contentField);
indexWriter.addDocument(document);
//关闭indexWriter
indexWriter.close();
}
运行结果如下截图:
2、Lucene使用索引 检索相关数据
实现的思路如下:
<1>创建了文件/磁盘目录对象Directory 和 索引检索器IndexSearch ;
<2>创建IndexSearch 索引查询对象,然后根据关键字封装Query查询对象;
<3>调用search()方法,将查询的结果返回给TopDocs ,迭代里面所有的Document对象,显示查询结果;
<4>关闭IndexWriter 写入器,关闭Directory目录对象。
public void SearchIndex() throws Exception{
/**
* 1、创建一个 IndexSearch对象
* 2、调用search方法进行检索
* 3、输出内容
*/
//创建一个 IndexSearch对象
File file = new File("D:\\indexDir");
Directory directory = FSDirectory.open(file.toPath());
IndexReader reader = DirectoryReader.open(directory);
IndexSearcher indexSearcher = new IndexSearcher(reader);
//调用search方法进行检索
Analyzer analyzer = new StandardAnalyzer();
QueryParser queryParser = new QueryParser("content",analyzer);
Query query = queryParser.parse("baidu");//关键词
TopDocs topDocs = indexSearcher.search(query, 2);
int count = topDocs.totalHits;//根据关键词查询出来的总的记录数
ScoreDoc[] scoreDocs = topDocs.scoreDocs;
List<Article> articleList = new ArrayList<Article>();
for(ScoreDoc scoreDoc:scoreDocs){
float score = scoreDoc.score;//关键词得分
int index = scoreDoc.doc;//索引的下标
Document document = indexSearcher.doc(index);
//把document转化成article
Article article = new Article();
article.setId(Long.parseLong(document.get("id")));//document.getField("id").stringValue()
article.setTitle(document.get("title"));
article.setContent(document.get("content"));
articleList.add(article);
}
for(Article article:articleList){
System.out.println(article.getId());
System.out.println(article.getTitle());
System.out.println(article.getContent());
}
}
运行结果如下截图:
项目总体结构图:
项目源码下载路径:https://pan.baidu.com/s/1jHKgYwA