因为没有找到以前的项目案例,所以我简单搭建了一个普通的maven工程,演示一下在项目中的使用,当然在实际项目中不会这么简单的使用,一般访问量高的门户网站都会用到分布式架构,solr也才采用集群的配置。本文只演示简单操作,提供学习。
项目结构:
schema.xml配置文件中对应的业务域,以及使用的分词器:
需要使用到的依赖,在上文中https://blog.csdn.net/qq_37138756/article/details/80804524已经说过了,这里需要在配置文件中配置一个HttpSolrServer。
<!-- 单击版solrJ -->
<bean id="httpSolrServer" class="org.apache.solr.client.solrj.impl.HttpSolrServer">
<constructor-arg index="0" value="http://localhost:8085/solr/core"/>
</bean>
1.后台管理系统中的一键导入索引(在初次使用索引库中的时候):
前台:
//导入数据到索引库
function queryUser(){
var newurl="";
$.ajax({
url:"<%=request.getContextPath()%>/user/importUser",
type:"post",
async:false,
datatype:"html/text",
success:function(data){
if(data == "true"){
alert("导入索引成功");
}else{
alert("导入索引失败");
}
},
error:function(){
alert("导入索引失败");
}
})
return newurl;
}
在使用者点击"一键导入索引"的时候,ajax去后台请求数据库,在dao层查询到数据,将查询到的数据写入到solr索引中,需要注意的是,查询到的数据属性跟域对应
mapper层:
<mapper namespace="com.ssm.dao.IUserDao" >
<resultMap id="BaseResultMap" type="com.ssm.dto.User">
<result column="id" property="id" jdbcType="INTEGER" />
<result column="name" property="name" jdbcType="VARCHAR" />
<result column="password" property="password" jdbcType="VARCHAR" />
<result column="age" property="age" jdbcType="INTEGER" />
</resultMap>
<sql id="Base_Column_List">
id, name, password, age
</sql>
<!-- 查询用户-->
<select id="getAllUser" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from user
</select>
</mapper>
查询出来数据以后,我是在service层处理数据信息,将数据写入到solr索引库。返回的数据信息为List集合的User对象
User实体:
package com.ssm.dto;
public class User {
private String id;
private String name;
private String password;
private Integer age;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password == null ? null : password.trim();
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
service层:
@Override public String importUser() { String tag; //查询数据列表 List<User> allUser = userDao.getAllUser(); try { //遍历数据列表 for (User user : allUser) { //创建文档对象 SolrInputDocument document = new SolrInputDocument(); //向文档对象中添加域 document.addField("id", user.getId()); document.addField("name", user.getName()); document.addField("age", user.getAge()); document.addField("password", user.getPassword()); //把文档对象写入索引库 solrServer.add(document); } //提交 solrServer.commit(); return tag ="true"; } catch (SolrServerException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return tag ="fasle"; }
2.搜索实现:
controller层:
接收页面请求参数,调用服务层方法。根据页面需要(当前页,每页显示条数,总记录数,总页数,搜索到的数据信息列表)对返回结果进行处理,绑定到request域,跳转的逻辑视图。
/**
* 查询solr服务器索引
* @param conditions 查询条件
* @param page 页数
* @param rows 条数
* @return
*/
@RequestMapping(value="/userList")
public String userList(String conditions, Integer page ,Integer rows ,Model model) {
UserResult userResult = null;
try {
userResult = userService.quertSolrUserAll(conditions , page , rows); //Solr中查询
} catch (SolrServerException e) {
e.printStackTrace();
}
//把结果传递给页面
model.addAttribute("query", conditions); //查询条件
model.addAttribute("totalPages", userResult.getTotalPages()); //总页数
model.addAttribute("page", page); // 页数
model.addAttribute("recordCount", userResult.getRecordCount()); //条数
model.addAttribute("itemList", userResult.getUserList()); //文档信息
return "index";
}
controller成接受到的返回对象为UserResult,UserResult是定义返回对象:
package com.ssm.dto;
import java.util.List;
public class UserResult {
private Long recordCount;
private Integer totalPages;
private List<User> userList;
public Long getRecordCount() {
return recordCount;
}
public void setRecordCount(long numFound) {
this.recordCount = numFound;
}
public Integer getTotalPages() {
return totalPages;
}
public void setTotalPages(Integer totalPages) {
this.totalPages = totalPages;
}
public List<User> getUserList() {
return userList;
}
public void setUserList(List<User> userList) {
this.userList = userList;
}
}
Service层:通过controller层传递过来的查询条件,通过设置条件去solr中查询索引文档,并通过查询域设置高亮,讲查询到的信息返回。
根据参数:
页数:page,
条数:rows,
搜索关键字:conditions
当前页码由页面传来,每页显示有开发人员固定好。所以查询开始位置就能知道,页数也可以有总记录数跟每页显示条数记录下来。创建搜索对象SolrQuery,设置好查询条件,调用SolrQuery方法获得查询结果返回。
/**
* 查询solr服务器索引
* @param conditions 查询条件
* @param page 页数
* @param rows 条数
* @return
* @throws SolrServerException
*/
@Override
public UserResult quertSolrUserAll(String conditions, Integer page, Integer rows) throws SolrServerException {
//创建一个SolrQuery对象
SolrQuery query = new SolrQuery();
//设置查询条件
query.setQuery(conditions);
//设置分页条件
if(page <= 0){
page = 1;
}
query.setStart((page-1)*rows);
query.setRows(rows);
//设置默认搜索域
query.set("df", "name");
//开启高亮显示,显示颜色为红色
query.setHighlight(true);
query.setHighlightSimplePre("<span style='color:red'>");
query.setHighlightSimplePost("</span>");
//根据query查询索引库
QueryResponse queryResponse = solrServer.query(query);
//取查询结果
SolrDocumentList solrDocumentList = queryResponse.getResults();
//取查询结果总记录数
long numFound = solrDocumentList.getNumFound();
UserResult userResult = new UserResult(); //Solr结果返回对象
userResult.setRecordCount(numFound);
//取文档列表,需要取高亮显示
Map<String, Map<String, List<String>>> highlighting = queryResponse.getHighlighting();
List<User> userList = new ArrayList<>();
for (SolrDocument solrDocument : solrDocumentList) {
User user = new User();
//获取查询域
user.setId((String)solrDocument.get("id"));
user.setAge((Integer)solrDocument.get("age"));
user.setPassword((String)solrDocument.get("password"));
//取高亮
List<String> list = highlighting.get(solrDocument.get("id")).get("name");
String name = "";
if(list!=null&&list.size()>0){
name = list.get(0);
}else{
name = (String)solrDocument.get("name");
}
user.setName(name);
//添加到user列表
userList.add(user);
}
userResult.setUserList(userList);//索引信息
//计算总页数
int totalPage = (int) (numFound/rows);
if(totalPage%rows > 0) totalPage++;
//返回结果
userResult.setTotalPages(totalPage);
//返回结果
return userResult;
}
3.索引库维护:
当对数据库增加,删除,修改的时候,我们需要对solr索引库进行更新,可以写一套服务接口使用,在操作数据库的时候,来调用对应操作方法,来进行维护索引,达到实话同步的功能:
接口:
package com.ssm.service;
import org.apache.solr.client.solrj.SolrServerException;
import com.ssm.dto.User;
import java.io.IOException;
import java.util.List;
public interface SolrUtil {
//添加对象到全文检索
void solrAdd(User user) throws IOException, SolrServerException;
//全文检索中移除对象
void solrDeleteByIds(List<String> ids) throws IOException, SolrServerException;
void solrDeleteById(String id) throws IOException, SolrServerException;
}
实现类:
package com.ssm.service.Impl;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import javax.annotation.Resource;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.HttpSolrServer;
import org.apache.solr.common.SolrInputDocument;
import com.ssm.dto.User;
import com.ssm.service.SolrUtil;
public class SolrUtilImpl implements SolrUtil {
@Resource
private HttpSolrServer solrServer;
/**
* 添加,修改索引
*/
@Override
public void solrAdd(User user) throws IOException, SolrServerException {
if(user != null){
//创建文档对象
SolrInputDocument document = new SolrInputDocument();
//向文档对象中添加域
document.addField("id", user.getId());
document.addField("name", user.getName());
document.addField("age", user.getAge());
document.addField("password", user.getPassword());
//把文档对象写入索引库
solrServer.add(document);
solrServer.commit();
}
}
/**
* 删除多条索引
*/
@Override
public void solrDeleteByIds(List<String> ids) throws IOException, SolrServerException {
if(ids != null && ids.size() > 0){
solrServer.deleteById(ids);
solrServer.commit();
}
}
/**
* 删除索引
*/
@Override
public void solrDeleteById(String id) throws IOException, SolrServerException {
if(id != null){
solrServer.deleteById(id);
solrServer.commit();
}
}
}
以上就是利用solrj维护solr服务器文档库的简要方法,已经能满足基本使用详情请参考:https://blog.csdn.net/u012476983/article/details/53992158