中已经介绍了如何在项目中使用solr
今天再完善一下,把查询集成进去
我们对之前的文章进行了重新设计
import java.util.Date;
import org.apache.solr.client.solrj.beans.Field;
/**
* solr中保存的文章
*
* @author 程高伟
* @time 2017年5月7日下午7:51:23
*/
public class ArticleSolr {
// 文章id
@Field
private String id;
// 文章分类名称
@Field
private String category;
// 作者姓名
@Field
private String author;
// 文章标题
@Field
private String title;
// 文章内容
@Field
private String content;
// 发布时间
@Field
private Date createTime;
// 阅读量
@Field
private Integer readCount;
// 评论量
@Field
private Integer commentCount;
// 省去getter setter toString方法
}
现在我们在solr 控制台对之前定义的solr类型进行重新定义
在这个页面可以修改solr中的数据类型
我们添加一下文章分类,这个也是需要进行中文分词的数据类型选择text_ik
依次建立相应的字段(除了需要中文分词的类型为text_ik外,其他的比如时间可选选择date类型,阅读量可以选择int类型)
所有字段都可以在managed-schema中看到
好了,现在数据类型已经建立了,模型也定义好了。
我们插入一条测试数据
ArticleSolr article = new ArticleSolr();
article.setId("123456");
article.setTitle("项目中如何使用solr");
article.setAuthor("程高伟");
article.setCategory("solr");
article.setContent("之前写过solr的系列文章,包括对官方文档的学习和solrj的使用,但是今天想在项目中使用却发现很难将所有的知识点串联起来...");
article.setCreateTime(new Date());
article.setReadCount(189);
article.setCommentCount(2);
SolrUtil.saveSolrResource(article);
我们进入控制台
已经看到添加的数据了
我依次把我博客中的下面八篇文章添加进去
添加完成以后我们写一个controller
这个controller很简单就是根据用户的关键词调用solr搜索,返回结果
/**
* 搜索
*
* @author 程高伟
* @time 2017年5月7日下午8:27:35
*/
@Controller
public class SearchController {
@RequestMapping(value = "/search", method = RequestMethod.GET)
public String search(String keywords, Model model) throws SolrServerException, IOException {
List<ArticleSolr> articleList = SolrUtil.queryHighlight(keywords);
model.addAttribute("articleList", articleList);
return "admin/article/search";
}
}
高亮的代码
public static List<ArticleSolr> queryHighlight(String keywords) throws SolrServerException, IOException {
SolrQuery solrQuery = new SolrQuery();
solrQuery.setQuery("title:" + keywords + "or content:" + keywords+ "or author:" + keywords+ "or category:" + keywords); // 设置查询关键字
solrQuery.setHighlight(true); // 开启高亮
solrQuery.addHighlightField("title"); // 高亮字段
solrQuery.addHighlightField("content"); // 高亮字段
solrQuery.setHighlightSimplePre("<font color='red'>"); // 高亮单词的前缀
solrQuery.setHighlightSimplePost("</font>"); // 高亮单词的后缀
solrQuery.setSort("createTime", ORDER.desc); // 按照文章的发布时间排序
/**
* hl.snippets
* hl.snippets参数是返回高亮摘要的段数,因为我们的文本一般都比较长,含有搜索关键字的地方有多处,如果hl.snippets的值大于1的话,
* 会返回多个摘要信息,即文本中含有关键字的几段话,默认值为1,返回含关键字最多的一段描述。solr会对多个段进行排序。
* hl.fragsize
* hl.fragsize参数是摘要信息的长度。默认值是100,这个长度是出现关键字的位置向前移6个字符,再往后100个字符,取这一段文本。
*/
solrQuery.setHighlightFragsize(100);
QueryResponse query = client.query(solrQuery);
List<ArticleSolr> articleList = query.getBeans(ArticleSolr.class);
// System.out.println(query.getResponse().get("highlighting"));
Map<String, Map<String, List<String>>> highlightresult = query.getHighlighting();
// System.out.println(highlightresult);
for (int i = 0; i < articleList.size(); ++i) {
// System.out.println("文章:"+articleList.get(i));
String id = articleList.get(i).getId();
if (highlightresult.get(id) != null && highlightresult.get(id).get("title") != null) {
articleList.get(i).setTitle(highlightresult.get(id).get("title").get(0));
}
if (highlightresult.get(id) != null && highlightresult.get(id).get("content") != null) {
articleList.get(i).setContent(highlightresult.get(id).get("content").get(0));
}
}
return articleList;
}
最后的页面
<div class="dataTable_wrapper">
<table class="table table-striped table-bordered table-hover"
id="dataTables-example">
<thead>
<tr>
<th>文章名称</th>
<th>文章内容</th>
<th>发布日期</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<c:forEach items="${articleList }" var="article" varStatus="status">
<tr>
<td>${article.title }</td>
<td>${article.content }</td>
<td><fmt:formatDate value="${article.createTime }" type="date" pattern="yyyy-MM-dd HH:mm:ss"/></td>
<td>
<a href="${ctx }/blog/${article.id }" class="btn btn-outline btn-primary btn-xs btn-preview"><i class="fa fa-file-text-o"></i> 预览</a>
</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
效果
搜索Spring Boot的高亮显示
微信公众号的高亮以及分词效果
不要在意这里的分页,这里的分页是datatables的分页,与solr无关。