之前的博客搜索栏用的是 sql 模糊查询进行查找,最近学完lucene,要学以致用啊,就把sql搜索给替换下来吧

  中间遇到一些问题,也是学过程中没有提到的,所以说,还是实践出真知啊。

lucene分开来讲的话,我感觉就是两大块:索引维护、搜索索引

索引维护包括:添加索引、删除索引、更新索引

public class BlogIndex {
// lucene 路径在 bean 里面配置
private String lucenePath;public String getLucenePath() {
return lucenePath;
} public void setLucenePath(String lucenePath) {
this.lucenePath = lucenePath;
} /**
* 获取对lucene的写入方法
*/
private IndexWriter getWriter() throws Exception {
Directory dir = FSDirectory.open(new File(lucenePath).toPath());
IndexWriterConfig config = new IndexWriterConfig(new IKAnalyzer());
IndexWriter indexWriter = new IndexWriter(dir,config);
return indexWriter;
} /**
* 增加索引
*/
public void addIndex(BlogCustom blog) throws Exception {
IndexWriter indexWriter = getWriter();
Document doc = new Document(); doc.add(new StringField("id",String.valueOf(blog.getId()),Field.Store.YES));
doc.add(new TextField("title",blog.getTitle(),Field.Store.YES));
doc.add(new TextField("summary",blog.getSummary(),Field.Store.YES));
doc.add(new TextField("keyWord",blog.getKeyWord(),Field.Store.YES));
indexWriter.addDocument(doc);
indexWriter.close();
} /**
* 更新索引
*/
public void updateIndex(BlogCustom blog) throws Exception {
IndexWriter indexWriter = getWriter();
Document doc = new Document(); doc.add(new StringField("id",blog.getId()+"",Field.Store.YES));
doc.add(new TextField("title",blog.getTitle(),Field.Store.YES));
doc.add(new TextField("summary",blog.getSummary(),Field.Store.YES));
doc.add(new TextField("keyWord",blog.getKeyWord(),Field.Store.YES)); indexWriter.updateDocument(new Term("id",String.valueOf(blog.getId())),doc);
indexWriter.close();
} /**
* 删除索引
*/
public void deleteIndex(String blogId) throws Exception {
IndexWriter indexWriter = getWriter();
indexWriter.deleteDocuments(new Term("id",blogId));
indexWriter.close();
}

搜索索引就比较复杂一点

    /**
* 搜索索引
*/
public List<BlogCustom> searchBlog(String q) throws Exception{
//创建一个 Analyzer对象,IKAnalyzer 对象
Analyzer analyzer = new IKAnalyzer();
List<BlogCustom> blogList = new LinkedList<>();
Directory dir = FSDirectory.open(new File(lucenePath).toPath());
IndexReader indexReader = DirectoryReader.open(dir);
IndexSearcher indexSearch = new IndexSearcher(indexReader); // 多域查询
String[] fields = {"id","title","summary","keyWord"};
// 表示多个条件之间的关系,SHOULD 只要一个域里面有满足我们的搜索的内容就行
// 数组长度 = fields 长度
BooleanClause.Occur[] clauses = { BooleanClause.Occur.SHOULD,BooleanClause.Occur.SHOULD,
BooleanClause.Occur.SHOULD,BooleanClause.Occur.SHOULD };
// 参数: 关键词、多域、条件之间的关系、中文分析器
Query query = MultiFieldQueryParser.parse(q, fields, clauses, analyzer);
// 查询结果,设置最多返回100条数据
TopDocs topDocs = indexSearch.search(query, 100); // 高亮关键词
// 高亮格式
SimpleHTMLFormatter formatter = new SimpleHTMLFormatter("<font style='color:red;'>","</font>");
// 关键词查询出来的指定位置
QueryScorer scorer = new QueryScorer(query);
// 在关键词指定位置,加上设定的高亮格式
Highlighter highlighter = new Highlighter(formatter,scorer);
// 设置含有关键字文本块的大小
highlighter.setTextFragmenter(new SimpleSpanFragmenter(scorer)); ScoreDoc[] scoreDocs = topDocs.scoreDocs;
//遍历查询结果,放入blogList
for(ScoreDoc scoreDoc : scoreDocs){
// 取当前文档
Document doc = indexSearch.doc(scoreDoc.doc);
BlogCustom blog = new BlogCustom(); // 取出关键词
int id = Integer.parseInt(doc.get("id"));
blog.setId(id);
String title = doc.get("title");
String summary = doc.get("summary");
String keyWord = doc.get("keyWord"); // 给不为空的关键词,加上高亮显示
if(title!=null) {
TokenStream tokenStream = analyzer.tokenStream("title", title);
String hTitle = highlighter.getBestFragment(tokenStream, title);
if(StringUtil.isEmpty(hTitle)) {
blog.setTitle(title);
}else {
blog.setTitle(hTitle);
}
}
if(summary!=null) {
TokenStream tokenStream = analyzer.tokenStream("summary", summary);
String hSummary = highlighter.getBestFragment(tokenStream, summary);
if(StringUtil.isEmpty(hSummary)) {
blog.setSummary(summary);
}else {
blog.setSummary(hSummary);
}
}
if(keyWord!=null) {
TokenStream tokenStream = analyzer.tokenStream("keyWord", keyWord);
String hKeyWord = highlighter.getBestFragment(tokenStream, keyWord);
if(StringUtil.isEmpty(hKeyWord)) {
blog.setKeyWord(keyWord);
}else {
blog.setKeyWord(hKeyWord);
}
}
blogList.add(blog);
}
return blogList;
} }

完成 !

lucene实践 - 索引维护、多域查询、高亮显示的更多相关文章

  1. [Elasticsearch] 多字段搜索 (六) - 自定义_all字段,跨域查询及精确值字段

    自定义_all字段 在元数据:_all字段中,我们解释了特殊的_all字段会将其它所有字段中的值作为一个大字符串进行索引.尽管将所有字段的值作为一个字段进行索引并不是非常灵活.如果有一个自定义的_al ...

  2. Lucene 的 Field 域和索引维护

    一.Field 域 1.Field 属性 Field 是文档中的域,包括 Field 名和 Field 值两部分,一个文档可以包括多个 Field,Document 只是 Field 的一个承载体,F ...

  3. Lucene实现索引和查询

    0引言 随着万维网的发展和大数据时代的到来,每天都有大量的数字化信息在生产.存储.传递和转化,如何从大量的信息中以一定的方式找到满足自己需求的信息,使之有序化并加以利用成为一大难题.全文检索技术是现如 ...

  4. lucene&solr学习——索引维护

    1.索引库的维护 索引库删除 (1) 全删除 第一步:先对文档进行分析 public IndexWriter getIndexWriter() throws Exception { // 第一步:创建 ...

  5. lucene查询索引之Query子类查询——(七)

    0.文档名字:(根据名字索引查询文档)

  6. Lucene之索引库的维护:添加,删除,修改

    索引添加 Field域属性分类 添加文档的时候,我们文档当中包含多个域,那么域的类型是我们自定义的,上个案例使用的TextField域,那么这个域他会自动分词,然后存储 我们要根据数据类型和数据的用途 ...

  7. 一步一步跟我学习lucene(18)---lucene索引时join和查询时join使用演示样例

    了解sql的朋友都知道,我们在查询的时候能够採用join查询,即对有一定关联关系的对象进行联合查询来对多维的数据进行整理.这个联合查询的方式挺方便的.跟我们现实生活中的托人找关系类似,我们想要完毕一件 ...

  8. 01 lucene基础 北风网项目培训 Lucene实践课程 索引

    在创建索引的过程中IndexWriter会创建多个对应的Segment,这个Segment就是对应一个实体的索引段.随着索引的创建,Segment会慢慢的变大.为了提高索引的效率,IndexWrite ...

  9. SolrJ 复杂查询 高亮显示

    SolrJ 复杂查询 高亮显示 上一章搭建了Solr服务器和导入了商品数据,本章通过SolrJ去学习Solr在企业中的运用.笔者最先是通过公司的云客服系统接触的Solr,几百万的留言秒秒钟就查询并高亮 ...

随机推荐

  1. Lesson 15 Secrecy in industry

    Why is secrecy particularly important in the chemical industries? Two factors weigh heavily against ...

  2. win10常用快捷键总结

    前言: 很多快捷键在不同版本系统基本相同的,但是今天推送的这篇文章更多的介绍 win10快捷键,微软也是大力推广 旗舰系统 win10 ,所以大家提前升级,提前学习还是有必要的.毕竟2020年微软会放 ...

  3. python包管理历史

    1.标准库工具distutils,2000年发布,是包安装和发布工具 setup.python 程序,利用distutils 开发 示例: python setup.py install 安装一个包 ...

  4. Session共享解决方案

    使用nginx做的负载均衡添加一个ip_hash配置 一.开两个Tomcat写测试程序 @WebServlet("/nginxSessionServlet") public cla ...

  5. js--滑动块

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  6. python爬虫(四) 内涵段子

    import requests import time import json from urllib import request from urllib import parse url = 'h ...

  7. 原生JS 和 JQ 获取滚动条的高度,以及距离顶部的高度

    JQ:相对比较简便 获取浏览器显示区域(可视区域)的高度 : $(window).height(); 获取浏览器显示区域(可视区域)的宽度 : $(window).width(); 获取页面的文档高度 ...

  8. 学习java时在要求输出的数字带俩个小数点时,利用String.format时出现的问题

    public class StringFormatDemo { public static void main(String[] args) { //String.format 实现了四舍五入 Sys ...

  9. Codeforces 1304D. Shortest and Longest LIS

    根据题目,我们可以找最短的LIS和最长的LIS,找最短LIS时,可以将每一个increase序列分成一组,从左到右将最大的还未选择的数字填写进去,不同组之间一定不会存在s[i]<s[j]的情况, ...

  10. 已知空间三点组成的面求该面上某点的Z值

    已知空间三点,那么可以就可以确定空间三点组成的平面.此时可以根据某一点的X值和Y值,来求取该点在平面上的Z值.这个过程对于求三角面片上某点的高程或者权值特别有用,其本身也可以看作一种线性插值. 其算法 ...