Solr案例

需求

使用Solr实现电商网站中商品信息搜索功能,可以根据关键字、分类、价格搜索商品信息,也可以根据价格进行排序,并且实现分页功能。

架构分为:

(1)、solr服务器。(已经做完,同入门示例)

(2)、自己开发的应用(重点)

(3)、数据库mysql


自己开发的应用

Controller负责和前端页面进行请求和响应的交互

Service封装查询条件,调用dao。

Dao搜索索引库,返回搜索结果。

环境准备

Solr:4.10.3

Jdk环境:1.7.0_72(solr4.10不能使用jdk1.7以下)

Ide环境:Eclipse

Web服务器(servlet容器):Tomcat 7X

功能开发

第一步:创建web工程,导入jar包



--导入的jar包说明:

Solrj的包

Solr服务的日志包

Spring的包(包含springmvc)

核心包4个 core 、bean、context、expresstion

注解包aop

Web包web、webmvc

Commons日志包  common-logging

Jstl包


--导入静态资源和jsp页面说明:

静态资源放在webapp目录下,jsp页面放到/WEB-INF/目录下


第二步:Spring整合Solr、Springmvc

创建springmvc.xml

在config包下,创建springmvc.xml文件

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"

xmlns:context="http://www.springframework.org/schema/context"

xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-3.1.xsd

http://www.springframework.org/schema/mvc

http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context-3.1.xsd

http://www.springframework.org/schema/aop

http://www.springframework.org/schema/aop/spring-aop-3.1.xsd

http://www.springframework.org/schema/tx

http://www.springframework.org/schema/tx/spring-tx-3.1.xsd ">



class="org.springframework.web.servlet.view.InternalResourceViewResolver">





创建Web.xml

"1.0" encoding="UTF-8"?>

"http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">

  JD0719



springmvc

org.springframework.web.servlet.DispatcherServlet

contextConfigLocation

classpath:springmvc.xml

springmvc

/

Character Encoding

org.springframework.web.filter.CharacterEncodingFilter

encoding

UTF-8

Character Encoding

*.action


第三步:整合测试

需求:

访问搜索页面。


创建PageController类

package cn.gzsxt.solr.controller;


import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.PathVariable;

import org.springframework.web.bind.annotation.RequestMapping;


@Controller

public class PageController {


@RequestMapping(value="/{page}")

public String showPage(@PathVariable("page")String page){


return page;

}

}


注意事项

(1)Solr服务器要先开启。

(2)Solr服务器部署的Tomcat和本web应用的部署的Tomcat不是同一个。


(3)要同时启动两个Tomcat,要注意端口冲突问题。


修改Solr服务器的Tomcat的端口

--在server.xml文件中,修改端口

--tomcat端口说明:

   8005:关机端口

   8080:默认服务端口

   8009:请求转向端口。


--注意:这三个端口都需要修改。不然启动会冲突


本次课程中,将solr的tomcat端口,修改为8888.

 

修改Springmvc.xml

--修改Solr服务的端口

http://localhost:8888/solr/solrCore0719">




访问搜索页面

地址:http://localhost:8080/solr-demo-02-jd/product_list.action 





整合成功!!!


第四步:搜索功能实现

分析代码结构:

请求路径list.action

请求方式POST

请求参数queryString、catalog_name、price、curPage、sort(共5个)

返回结果定义Product 以及ProductModel



Pojo

分析

结合查询界面,分析得出:

--需要一个商品的pojo(Product),存放商品信息

--需要一个包装pojo(ResultModel),它包括商品列表信息、商品分页信息

创建Product类

public class Product {

//商品编号

private String pid;

//商品名称

private String name;

//商品分类名称

private String catalog_name;

//价格

private double price;

//商品描述

private String description;

//图片名称

private String picture;

}


创建ResultModel类

public class ResultModel {

private List productList;

//商品总数

private Long recordCount;

//总页数

private int pageCount;

//当前页

private int currentPage;

}


Dao

功能

接收service层传递过来的参数,根据参数查询索引库,返回查询结果。


创建ProductDao接口,定义一个查询方法

public interface ProductDao {


//查询商品信息,包括分页信息

public ResultModel queryProduct(SolrQuery query) throws Exception;

}


创建ProductDaoImpl,重新改查询方法

package cn.gzsxt.dao.impl;

 

import java.util.ArrayList;

import java.util.List;

import java.util.Map;

 

import org.apache.solr.client.solrj.SolrQuery;

import org.apache.solr.client.solrj.impl.HttpSolrServer;

import org.apache.solr.client.solrj.response.QueryResponse;

import org.apache.solr.common.SolrDocument;

import org.apache.solr.common.SolrDocumentList;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Repository;

 

import cn.gzsxt.bean.Product;

import cn.gzsxt.bean.ResultModel;

import cn.gzsxt.dao.ProductDao;

 

@Repository

public class ProductDaoImpl implements ProductDao {

 

@Autowired

private HttpSolrServer server;

 

@Override

public ResultModel queryProduct(SolrQuery query) throws Exception {

ResultModel result = new ResultModel();

//通过server查询索引库

QueryResponse response = server.query(query);

//获得查询结果

SolrDocumentList documentList = response.getResults();

//把查询结果总数设置到ResultModel

result.setRecordCount(documentList.getNumFound());

 

List productList = new ArrayList<>();

Product product = null;

//高亮信息

Map>> highlighting = response

.getHighlighting();

for (SolrDocument solrDocument : documentList) {

product = new Product();

product.setPid((String) solrDocument.get("id"));

 

String prodName = (String) solrDocument.get("product_name");

 

List list = highlighting.get(solrDocument.get("id")).get(

"product_name");

if (list != null)

prodName = list.get(0);

 

product.setName(prodName);

product.setCatalog_name((String) solrDocument

.get("product_catalog_name"));

product.setPrice((float) solrDocument.get("product_price"));

product.setPicture((String) solrDocument.get("product_picture"));

 

productList.add(product);

}

 

//把商品列表放到ResultMap中

result.setProductList(productList);

return result;

}

 

}


Service

功能分析

接收action传递过来的参数,根据参数拼装一个查询条件,调用dao层方法,查询商品列表。

接收返回的商品列表和商品的总数量,根据每页显示的商品数量计算总页数。

创建ProductService接口,定义一个查询方法

public interface ProductService {

public ResultModel queryProduct(String queryString, String cataName,

String price, String sort, Integer curPage) throws Exception;

}

创建ProductServiceImpl类,重写改查询方法

package cn.gzsxt.service.impl;


import org.apache.solr.client.solrj.SolrQuery;

import org.apache.solr.client.solrj.SolrQuery.ORDER;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;


import cn.gzsxt.dao.ProductDao;

import cn.gzsxt.service.ProductService;

import cn.gzsxt.vo.ResultModel;


@Service

public class ProductServiceImpl implements ProductService {


@Autowired

private ProductDao productDao;

@Override

public ResultModel queryProduct(String queryString, String cataName,

String price, String sort, Integer curPage) throws Exception {

//封装查询条件

SolrQuery query = new SolrQuery();

//判断查询条件是否为空

if(!"".equals(queryString)&& null != queryString){

query.setQuery(queryString);

}else{

query.setQuery("*:*");

}

//判断过滤条件是否为空

if(!"".equals(cataName)&& null !=cataName){

query.addFilterQuery("product_catalog_name:"+cataName);

}

//判断商品价格是否为空

if(!"".equals(price) && null != price){

String[] prices = price.split("-");

if(prices.length == 2){

query.addFilterQuery("product_price:["+prices[0]+" TO "+prices[1]+"]");

}

}

//设置排序

if("1".equals(sort)){

query.setSort("product_price", ORDER.desc);

}else {

query.setSort("product_price", ORDER.asc);

}

//设置分页信息

if(null == curPage){

curPage = 1;

}

query.setStart((curPage-1)*20);

query.setRows(20);  //每页20条数据

//设置默认搜索域

query.set("df","product_name");

query.setHighlight(true);

query.addHighlightField("product_name");

query.setHighlightSimplePre("");

query.setHighlightSimplePost("");

ResultModel result = productDao.queryProduct(query);

result.setCurrentPage(curPage);

//总页数 = 总数量 / 每页数据条数  结果向上取整

double ceil = Math.ceil(result.getRecordCount().doubleValue()/20);

result.setPageCount((int)ceil);

return result;

}

}


Controller

创建ProductController类,定义查询接口

package cn.gzsxt.controller;


import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Controller;

import org.springframework.ui.ModelMap;

import org.springframework.web.bind.annotation.RequestMapping;


import cn.gzsxt.service.ProductService;

import cn.gzsxt.vo.ResultModel;


@Controller

public class ProductController {


@Autowired

private ProductService productService;

@RequestMapping("/list.action")

public String queryProduct(String queryString, String catalog_name,

String price, String sort, Integer curPage, ModelMap model)

throws Exception {


ResultModel resultModel = productService.queryProduct(queryString, catalog_name,

price, sort, curPage);

model.addAttribute("result", resultModel);

model.addAttribute("queryString", queryString);

model.addAttribute("catalog_name", catalog_name);

model.addAttribute("price", price);

model.addAttribute("sort", sort);

model.addAttribute("page", curPage);

return "product_list";

}

}



测试搜索功能

地址:http://localhost:8080/solr-demo-02-jd/list.action 

你可能感兴趣的:(Solr案例)