1.什么是solrJ
solrj是访问Solr服务的java客户端,提供索引和搜索的请求方法,SolrJ通常在嵌入在业务系统中,通过SolrJ的API接口操作Solr服务,如下图:
2.依赖的jar包
3.添加文档
(1) 实现步骤
第一步:创建一个java工程
第二步:导入jar包。包括solrJ的jar包。还需要
第三步:和Solr服务器建立连接。HttpSolrServer对象建立连接。
第四步:创建一个SolrInputDocument对象,然后添加域。
第五步:将SolrInputDocument添加到索引库。
第六步:提交。
(2) 代码实现
//向索引库中添加索引
@Test
public void addDocument() throws Exception {
//和solr服务器创建连接
//参数:solr服务器的地址
SolrServer solrServer = new HttpSolrServer("http://localhost:8080/solr");
//创建一个文档对象
SolrInputDocument document = new SolrInputDocument();
//向文档中添加域
//第一个参数:域的名称,域的名称必须是在schema.xml中定义的
//第二个参数:域的值
document.addField("id", "c0001");
document.addField("title_ik", "使用solrJ添加的文档");
document.addField("content_ik", "文档的内容");
document.addField("product_name", "商品名称");
//把document对象添加到索引库中
solrServer.add(document);
//提交修改
solrServer.commit();
}
3.删除文档
(1) 根据id删除
//删除文档,根据id删除
@Test
public void deleteDocumentByid() throws Exception {
//创建连接
SolrServer solrServer = new HttpSolrServer("http://localhost:8080/solr");
//根据id删除文档
solrServer.deleteById("c0001");
//提交修改
solrServer.commit();
}
(2) 根据查询删除
查询语法完全支持Lucene的查询语法。
//根据查询条件删除文档
@Test
public void deleteDocumentByQuery() throws Exception {
//创建连接
SolrServer solrServer = new HttpSolrServer("http://localhost:8080/solr");
//根据查询条件删除文档
solrServer.deleteByQuery("*:*");
//提交修改
solrServer.commit();
}
4.修改文档
在solrJ中修改没有对应的update方法,只有add方法,只需要添加一条新的文档,和被修改的文档id一致就,可以修改了。本质上就是先删除后添加。
5.查询文档
(1) 简单查询
//查询索引
@Test
public void queryIndex() throws Exception {
//创建连接
SolrServer solrServer = new HttpSolrServer("http://localhost:8080/solr");
//创建一个query对象
SolrQuery query = new SolrQuery();
//设置查询条件
query.setQuery("*:*");
//执行查询
QueryResponse queryResponse = solrServer.query(query);
//取查询结果
SolrDocumentList solrDocumentList = queryResponse.getResults();
//共查询到商品数量
System.out.println("共查询到商品数量:" + solrDocumentList.getNumFound());
//遍历查询的结果
for (SolrDocument solrDocument : solrDocumentList) {
System.out.println(solrDocument.get("id"));
System.out.println(solrDocument.get("product_name"));
System.out.println(solrDocument.get("product_price"));
System.out.println(solrDocument.get("product_catalog_name"));
System.out.println(solrDocument.get("product_picture"));
}
}
(2) 复杂查询
其中包含查询、过滤、分页、排序、高亮显示等处理。
//复杂查询索引
@Test
public void queryIndex2() throws Exception {
//创建连接
SolrServer solrServer = new HttpSolrServer("http://localhost:8080/solr");
//创建一个query对象
SolrQuery query = new SolrQuery();
//设置查询条件
query.setQuery("钻石");
//过滤条件
query.setFilterQueries("product_catalog_name:幽默杂货");
//排序条件
query.setSort("product_price", ORDER.asc);
//分页处理
query.setStart(0);
query.setRows(10);
//结果中域的列表
query.setFields("id","product_name","product_price","product_catalog_name","product_picture");
//设置默认搜索域
query.set("df", "product_keywords");
//高亮显示
query.setHighlight(true);
//高亮显示的域
query.addHighlightField("product_name");
//高亮显示的前缀
query.setHighlightSimplePre("<em>");
//高亮显示的后缀
query.setHighlightSimplePost("</em>");
//执行查询
QueryResponse queryResponse = solrServer.query(query);
//取查询结果
SolrDocumentList solrDocumentList = queryResponse.getResults();
//共查询到商品数量
System.out.println("共查询到商品数量:" + solrDocumentList.getNumFound());
//遍历查询的结果
for (SolrDocument solrDocument : solrDocumentList) {
System.out.println(solrDocument.get("id"));
//取高亮显示
String productName = "";
Map<String, Map<String, List<String>>> highlighting = queryResponse.getHighlighting();
List<String> list = highlighting.get(solrDocument.get("id")).get("product_name");
//判断是否有高亮内容
if (null != list) {
productName = list.get(0);
} else {
productName = (String) solrDocument.get("product_name");
}
System.out.println(productName);
System.out.println(solrDocument.get("product_price"));
System.out.println(solrDocument.get("product_catalog_name"));
System.out.println(solrDocument.get("product_picture"));
}
}
6.案例实现
(1) 原型分析
(2) 系统架构
(3) 工程
① 创建一个web工程导入jar包
springmvc的相关jar包
solrJ的jar包
Example\lib\ext下的jar包
② springmvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<context:component-scan base-package="com.itheima.jd"/>
<!-- 配置注解驱动,如果配置此标签可以不用配置处理器映射器和适配器 -->
<mvc:annotation-driven/>
<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!-- SolrServer的配置 -->
<bean id="httpSolrServer" class="org.apache.solr.client.solrj.impl.HttpSolrServer">
<constructor-arg index="0" value="http://localhost:8080/solr"/>
</bean>
</beans>
③ web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>solr-jd</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<!-- 配置前段控制器 -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<!-- 指定springmvc配置文件的路径
如果不指定默认为:/WEB-INF/${servlet-name}-servlet.xml
-->
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
<!-- 解决post乱码问题 -->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
④ Dao
功能:接收service层传递过来的参数,根据参数查询索引库,返回查询结果。
参数:SolrQuery对象
返回值:一个商品列表List<ProductModel>。
方法定义:public List<ProductModel> getResultModelFromSolr(QueryVo vo) throws Exception;
商品对象模型:
public class ProductModel {
// 商品编号
private String pid;
// 商品名称
private String name;
// 商品分类名称
private String catalog_name;
// 价格
private float price;
// 商品描述
private String description;
// 图片名称
private String picture;
}
@Repository
public class SolrDaoImpl implements SolrDao {
@Autowired
private SolrServer solrServer;
public List<ProductModel> getResultModelFromSolr(QueryVo vo) throws Exception{
SolrQuery solrQuery = new SolrQuery();
//关键词
if(null != vo.getQueryString() && !"".equals(vo.getQueryString())){
solrQuery.setQuery(vo.getQueryString());
solrQuery.set("df", "product_keywords");
}
//商品类型
if(null != vo.getCatalog_name() && !"".equals(vo.getCatalog_name().trim())){
solrQuery.addFilterQuery("product_catalog_name:" + vo.getCatalog_name());
}
//价格
if(null != vo.getPrice() && !"".equals(vo.getPrice().trim())){
String[] split = vo.getPrice().split("-");
if(split.length == 2){
solrQuery.addFilterQuery("product_price:[" + split[0] + " TO " + split[1] + "]");
}else{
solrQuery.addFilterQuery("product_price:[" + split[0] + " TO *]");
}
}
//价格排序
if("1".equals(vo.getSort())){
solrQuery.setSort("product_price", ORDER.desc);
}else{
solrQuery.setSort("product_price", ORDER.asc);
}
//显示的域
//solrQuery.setFields("id,product_name,product_price");
//1:设置高亮开关
solrQuery.setHighlight(true);
//2:需要高亮的域
solrQuery.addHighlightField("product_name");
//3:高亮的简单样式 前缀
solrQuery.setHighlightSimplePre("<span style='color:red'>");
//4:高亮的简单样式 后缀
solrQuery.setHighlightSimplePost("</span>");
QueryResponse response = solrServer.query(solrQuery);
//取出高亮
Map<String, Map<String, List<String>>> highlighting = response.getHighlighting();
//取出结果集
SolrDocumentList docs = response.getResults();
//打印总条数
System.out.println("总条数:" + docs.getNumFound());
//结果集
List<ProductModel> productModels = new ArrayList<ProductModel>();
//閬嶅巻
for (SolrDocument doc : docs) {
ProductModel productModel = new ProductModel();
//ID
String id = (String) doc.get("id");
productModel.setPid(id);
//
Map<String, List<String>> map = highlighting.get(id);
List<String> list = map.get("product_name");
//判断高亮必须不为空
if(null != list && list.size() > 0){
String name = list.get(0);
productModel.setName(name);
}
//价格
productModel.setPrice((float) doc.get("product_price"));
//商品图片
productModel.setPicture((String) doc.get("product_picture"));
//商品类型
productModel.setCatalog_name((String) doc.get("product_catalog_name"));
productModels.add(productModel);
}
return productModels;
}
}
⑤ Service
功能:接收action传递过来的参数,根据参数拼装一个查询条件,调用dao层方法,查询商品列表。接收返回的商品列表和商品的总数量,根据每页显示的商品数量计算总页数。
参数:
【1】查询条件:字符串
【2】商品分类的过滤条件:商品的分类名称,字符串
【3】商品价格区间:传递一个字符串,满足格式:“0-100、101-200、201-*”
【4】排序条件:页面传递过来一个升序或者降序就可以,默认是价格排序。0:升序1:降序
【5】分页信息:每页显示的记录条数创建一个常量60条。传递一个当前页码就可以了。
业务逻辑
【1】根据参数创建查询对象
【2】调用dao执行查询。
【3】根据总记录数计算总页数。
返回值:ResultModel
方法定义:ResultModel queryProduct(String queryString, String caltalog_name, String price, String sort, Integer page) throws Exception;
@Service
public class SolrServiceImpl implements SolrService {
@Autowired
private SolrDao solrDao;
public List<ProductModel> getResultModelFromSolr(QueryVo vo) throws Exception {
return solrDao.getResultModelFromSolr(vo);
}
}
⑥ controller
功能:接收页面传递过来的参数调用service查询商品列表。将查询结果返回给jsp页面,还需要查询参数的回显。
参数:
【1】查询条件:字符串
【2】商品分类的过滤条件:商品的分类名称,字符串
【3】商品价格区间:传递一个字符串,满足格式:“0-100、101-200、201-*”
【4】排序条件:页面传递过来一个升序或者降序就可以,默认是价格排序。0:升序1:降序
【5】分页信息:每页显示的记录条数创建一个常量60条。传递一个当前页码就可以了。
【6】Model:相当于request。
返回结果:String类型,就是一个jsp的名称。
public class QueryVo {
//关键词
private String queryString;
//过滤条件 商品类型
//价格区间
private String catalog_name;
private String price;
//排序 1 正 0倒
private String sort;
}
/**
* 商品搜索
* @author lx
*
*/
@Controller
public class ProductController {
@Autowired
SolrService solrService;
//搜索
@RequestMapping("/list.action")
public String list(QueryVo vo,Model model) throws Exception{
//结果集
List<ProductModel> productList = solrService.getResultModelFromSolr(vo);
model.addAttribute("productList", productList);
model.addAttribute("catalog_name", vo.getCatalog_name());
model.addAttribute("price", vo.getPrice());
model.addAttribute("sort", vo.getSort());
model.addAttribute("queryString", vo.getQueryString());
return "product_list";
}
}
⑦ jsp等相关页面