之前的博客搜索栏用的是 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. Java中的基本数据类型语法补充

    变量要先赋值后使用 不给变量赋值代表什么 不赋值就使用会怎样 (会报错) 计算并赋值运算符 作用是为了让代码更加简洁.比如 a = a + 10,可以简化为 a+=10 += -= *= /= %= ...

  2. 操作系统OS - 重装Windows7卡在completing installation

    1. shift + f10 2. cd oobe 3. Msoobe

  3. 在 ubuntu 中安装python虚拟环境

    直接看命令一路操作(注:python3 下): 1.安装虚拟环境: sudo pip3 install virtualenv 2.安装虚拟环境扩展管理工具: sudo pip3 install vir ...

  4. Python学习第十一课——装饰器

    #装饰器:本质就是函数,为其他函数附加功能原则:1.不修改被修饰函数的源代码2.不修改被修饰函数的调用方式 装饰器=高阶函数+函数嵌套+闭包 #高阶函数 ''' 高阶函数定义: 1.函数接受的参数是一 ...

  5. python绘制疫情图

    python中进行图表绘制的库主要有两个:matplotlib 和 pyecharts, 相比较而言: matplotlib中提供了BaseMap可以用于地图的绘制,但是个人觉得其绘制的地图不太美观, ...

  6. 【JAVA蓝桥杯】基础练习2 十六进制转十进制

    资源限制 时间限制:1.0s   内存限制:512.0MB 问题描述 从键盘输入一个不超过8位的正的十六进制数字符串,将它转换为正的十进制数后输出. 注:十六进制数中的10~15分别用大写的英文字母A ...

  7. [python]ubuntu下的python2和python3

    在终端分别输入python,python2,python3python和python2默认都是python2python3才是python3 Ubuntu下是默认没有pip的,需要自己手动安装 sud ...

  8. centos7搭建svn服务器及客户端设置

    centos7搭建svn服务器及客户端设置 centos7貌似预装了svn服务(有待确认),因此我们直接启动该服务即可 一.svn服务端配置(服务器IP假设为192.168.100.1) 步骤1:创建 ...

  9. 去除input边框 input去除边框 去除input获取焦点时的蓝色外边框

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  10. 五 Mybatis一对一关联查询的两种方式(基于resultType&基于resultMap)

    关联查询: 一个用户对应多个订单,一个订单只有一个用户 订单关联用户:两种方式 一:基于resultTYpe,一个与表关系一样的pojo实现 主表订单,从表用户 首先要有一个与关联查询表关系一样的po ...