之前的博客搜索栏用的是 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. Python爬虫解析网页的4种方式 值得收藏

    用Python写爬虫工具在现在是一种司空见惯的事情,每个人都希望能够写一段程序去互联网上扒一点资料下来,用于数据分析或者干点别的事情. ​ 我们知道,爬虫的原理无非是把目标网址的内容下载下来存储到内存 ...

  2. Python压缩文件/文件夹

    [Python压缩文件夹]导入“zipfile”模块 def zip_ya(startdir,file_news): startdir = ".\\123" #要压缩的文件夹路径 ...

  3. rc

    1,协同过滤. 2,协方差:用来衡量,他们的变化趋势是不是一致的. 3,皮尔逊相关系数:-1,负相关.1:正相关. 4,用皮尔逊相关系数来算相关性是最多的.

  4. VUE学习笔记二

    package.json不可以写注释!!!!!!!!!!初始化:npm init -y 有时候使用 npm i node-sass -D 装不上,这时候,就必须使用  cnpm i node-sass ...

  5. c++将字符转换成字符串

    转载:https://blog.csdn.net/dididisailor/article/details/83189135 char c; string str; stringstream stre ...

  6. 浏览器输入URL后HTTP请求返回的完整过程

    图:

  7. 阿里云服务器Ubantu16.04升级python3.6

    从ppa上下载下载python3.6 sudo apt-get install software-properties-common#使用 “add-apt-repository” 脚本添加 ppa ...

  8. ActiveMQ--模式(队列模式/主题模式)

    两种模式:队列模式/主题模式 pom.xml <dependency> <groupId>org.apache.activemq</groupId> <art ...

  9. Docker 问题[Warning] IPv4 forwarding is disabled. Networking will not work.

    Docker 问题[Warning] IPv4 forwarding is disabled. Networking will not work. 在使用Dockerfile创建Docker镜像的时候 ...

  10. 142、Java内部类之在普通方法里面定义内部类

    01.代码如下: package TIANPAN; class Outer { // 外部类 private String msg = "Hello World !"; publi ...