PYG电商项目开发 -- day07 spring-data-solr实现首页搜索功能

一、solr环境的准备


1、linux下单机版solr配置以及用IK分词器


详情请见:https://blog.csdn.net/wingzhezhe/article/details/73368610


2、配置SKU表tb_item相关的solr域字段


将下列字段加到solrHome中的schema.xml配置文件中


        <field name="item_goodsid" type="long" indexed="true" stored="true"/>
	<field name="item_title" type="text_ik" indexed="true" stored="true"/>
	<field name="item_price" type="double" indexed="true" stored="true"/>
	<field name="item_image" type="string" indexed="false" stored="true" />
	<field name="item_category" type="string" indexed="true" stored="true" />
	<field name="item_seller" type="text_ik" indexed="true" stored="true" />
	<field name="item_brand" type="string" indexed="true" stored="true" />

	<field name="item_keywords" type="text_ik" indexed="true" stored="false" multiValued="true"/>
	<copyField source="item_title" dest="item_keywords"/>
	<copyField source="item_category" dest="item_keywords"/>
	<copyField source="item_seller" dest="item_keywords"/>
	<copyField source="item_brand" dest="item_keywords"/>

	<dynamicField name="item_spec_*" type="string" indexed="true" stored="true" />


<fieldType name="text_ik" class="solr.TextField">
     <analyzer class="org.wltea.analyzer.lucene.IKAnalyzer"/>
</fieldType>


二、spring-data-solr环境搭建以及测试


1、导入依赖的jar包


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.test</groupId>
	<artifactId>spring_solr_test</artifactId>
	<version>0.0.1-SNAPSHOT</version>

	<dependencies>
		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-solr</artifactId>
			<version>1.5.5.RELEASE</version>
		</dependency>

		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.12</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>4.2.4.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>1.2.28</version>
		</dependency>
	</dependencies>
</project>


2、加入配置文件




<?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:solr="http://www.springframework.org/schema/data/solr"
	xsi:schemaLocation="http://www.springframework.org/schema/data/solr 
  		http://www.springframework.org/schema/data/solr/spring-solr-1.0.xsd
		http://www.springframework.org/schema/beans 
		http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context 
		http://www.springframework.org/schema/context/spring-context.xsd">
	<!-- solr服务器地址 -->
	<solr:solr-server id="solrServer" url="http://192.168.25.128:8080/solr" />
	<!-- solr模板,使用solr模板可对索引库进行CRUD的操作 -->
	<bean id="solrTemplate" class="org.springframework.data.solr.core.SolrTemplate">
		<constructor-arg ref="solrServer" />
	</bean>
</beans>


3、创建pojo


package com.pinyougou.pojo;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;

import org.apache.solr.client.solrj.beans.Field;

/**
 * 实体类
 * @author wingz
 *
 */
public class TbItem  implements Serializable{
    
	/**
	 * 使用Field注解进行属性和域字段的映射
	 */
	@Field("id")
	private Long id;

    @Field("item_title")
    private String title;

    private String sellPoint;

    @Field("item_price")
    private BigDecimal price;

    private Integer stockCount;

    private Integer num;

    private String barcode;

    @Field("item_image")
    private String image;

    private Long categoryid;

    private String status;

    private Date createTime;

    private Date updateTime;

    private String itemSn;

    private BigDecimal costPirce;

    private BigDecimal marketPrice;

    private String isDefault;

    @Field("item_goodsid")
    private Long goodsId;

    private String sellerId;

    private String cartThumbnail;

    @Field("item_category")
    private String category;

    @Field("item_brand")
    private String brand;

    private String spec;
    
    @Field("item_seller")
    private String seller;

   // 省略get/set方法...
}


4、创建测试类,进行测试


package cn.itcast.solr.test;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.solr.core.SolrTemplate;
import org.springframework.data.solr.core.query.Criteria;
import org.springframework.data.solr.core.query.HighlightOptions;
import org.springframework.data.solr.core.query.HighlightQuery;
import org.springframework.data.solr.core.query.Query;
import org.springframework.data.solr.core.query.SimpleHighlightQuery;
import org.springframework.data.solr.core.query.SimpleQuery;
import org.springframework.data.solr.core.query.SolrDataQuery;
import org.springframework.data.solr.core.query.result.HighlightEntry.Highlight;
import org.springframework.data.solr.core.query.result.HighlightPage;
import org.springframework.data.solr.core.query.result.ScoredPage;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.pinyougou.pojo.TbItem;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext-solr.xml")
public class SolrManager {

	@Autowired
	private SolrTemplate solrTemplate;

	@Test
	public void testAddOne() {

		TbItem item = new TbItem();
		/**
		 * solr域字段:
		 * 
		 * <field name="item_goodsid" type="long" indexed="true" stored="true"/>
		 * <field name="item_title" type="text_ik" indexed="true" stored="true"/>
		 * <field name="item_price" type="double" indexed="true" stored="true"/>
		 * <field name="item_image" type="string" indexed="false" stored="true" />
		 * <field name="item_category" type="string" indexed="true" stored="true" />
		 * <field name="item_seller" type="text_ik" indexed="true" stored="true" />
		 * <field name="item_brand" type="string" indexed="true" stored="true" />
		 * 
		 */

		item.setGoodsId(1111l);
		item.setTitle("测试商品数据");
		item.setPrice(new BigDecimal("10000"));
		item.setImage("图片路径");
		item.setCategory("分类名称");
		item.setSeller("商家");
		item.setBrand("小米");
		item.setId(2l);

		solrTemplate.saveBean(item);

		solrTemplate.commit();

	}

	@Test
	public void testDelete() {

		// 根据id删除
		//solrTemplate.deleteById("2");

		List<String> list = new ArrayList<String>();
		list.add("1111");

		SolrDataQuery query = new SimpleQuery();
		Criteria criteria = new Criteria("item_goodsid").contains(list);
		query.addCriteria(criteria);
		// 根据条件删除
		solrTemplate.delete(query);

		solrTemplate.commit();

	}

	/**
	 * 测试普通查询
	 */
	@Test
	public void testQuery() {

		// 创建一个SimpleQuery,用来存储条件
		Query query = new SimpleQuery();
		// 创建条件 1、指定查询的域名 2、需要关键字
		Criteria criteria = new Criteria("item_title").contains("测试商品数据");
		// 把条件放到query中
		query.addCriteria(criteria);
		// 执行模板的查询方法
		ScoredPage<TbItem> queryForPage = solrTemplate.queryForPage(query, TbItem.class);

		System.out.println("总条数:" + queryForPage.getTotalElements());

		List<TbItem> content = queryForPage.getContent();
		for (TbItem tbItem : content) {
			System.out.println(tbItem.getTitle());
		}
	}

	/**
	 * 测试高亮查询
	 */
	@Test
	public void testHighLight() {
		// 创建高亮条件查询
		HighlightQuery query = new SimpleHighlightQuery();
		// 普通的条件
		Criteria criteria = new Criteria("item_title").contains("半身裙");
		query.addCriteria(criteria);

		// 设置高亮的属性
		HighlightOptions highlightOptions = new HighlightOptions();
		// 指定高亮的域
		highlightOptions.addField("item_title");
		// 前缀和后缀
		highlightOptions.setSimplePrefix("<span style=\"color:red\">");
		highlightOptions.setSimplePostfix("</span>");

		query.setHighlightOptions(highlightOptions);

		HighlightPage<TbItem> queryForHighlightPage = solrTemplate.queryForHighlightPage(query, TbItem.class);

		System.out.println(JSON.toJSONString(queryForHighlightPage, SerializerFeature.DisableCircularReferenceDetect));

		List<TbItem> content = queryForHighlightPage.getContent();
		for (TbItem tbItem : content) {
			List<Highlight> highlights = queryForHighlightPage.getHighlights(tbItem);
			String string = highlights.get(0).getSnipplets().get(0);
			tbItem.setTitle(string);
		}

		for (TbItem tbItem : content) {
			System.out.println(tbItem.getTitle());
		}
	}

}


三、搭建search相关项目


1、创建pinyougou-search-interface


(1)、创建jar包子模块




(2)、加入依赖


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>com.pinyougou</groupId>
		<artifactId>pinyougou-parent</artifactId>
		<version>0.0.1-SNAPSHOT</version>
	</parent>
	<artifactId>pinyougou-search-interface</artifactId>
	<dependencies>
		<dependency>
			<groupId>com.pinyougou</groupId>
			<artifactId>pinyougou-pojo</artifactId>
			<version>0.0.1-SNAPSHOT</version>
		</dependency>
	</dependencies>
</project>


2、创建pinyougou-search-service


(1)、创建war包子模块




(2)、加入依赖


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>com.pinyougou</groupId>
		<artifactId>pinyougou-parent</artifactId>
		<version>0.0.1-SNAPSHOT</version>
	</parent>
	<artifactId>pinyougou-search-service</artifactId>
	<packaging>war</packaging>

	<dependencies>
		<dependency>
			<groupId>com.pinyougou</groupId>
			<artifactId>pinyougou-common</artifactId>
			<version>0.0.1-SNAPSHOT</version>
		</dependency>
		<dependency>
			<groupId>com.pinyougou</groupId>
			<artifactId>pinyougou-dao</artifactId>
			<version>0.0.1-SNAPSHOT</version>
		</dependency>
		<dependency>
			<groupId>com.pinyougou</groupId>
			<artifactId>pinyougou-search-interface</artifactId>
			<version>0.0.1-SNAPSHOT</version>
		</dependency>

		<!-- 引入相关jar包 -->
		<!-- Spring -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-beans</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aspects</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jms</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context-support</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
		</dependency>
		<!-- dubbo相关 -->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>dubbo</artifactId>
		</dependency>
		<dependency>
			<groupId>org.apache.zookeeper</groupId>
			<artifactId>zookeeper</artifactId>
		</dependency>
		<dependency>
			<groupId>com.github.sgroschupf</groupId>
			<artifactId>zkclient</artifactId>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
		</dependency>
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
		</dependency>
		<dependency>
			<groupId>javassist</groupId>
			<artifactId>javassist</artifactId>
		</dependency>
		<dependency>
			<groupId>commons-codec</groupId>
			<artifactId>commons-codec</artifactId>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<scope>provided</scope>
		</dependency>
		<!-- 加入spring-data-solr -->
		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-solr</artifactId>
			<version>1.5.5.RELEASE</version>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.tomcat.maven</groupId>
				<artifactId>tomcat7-maven-plugin</artifactId>
				<version>2.2</version>
				<configuration>
					<!-- 指定端口 -->
					<port>9000</port>
					<!-- 请求路径 -->
					<path>/</path>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>


(3)、加入配置文件




applicationContext-service.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:dubbo="http://code.alibabatech.com/schema/dubbo" 
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc 
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://code.alibabatech.com/schema/dubbo 
        http://code.alibabatech.com/schema/dubbo/dubbo.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context.xsd">

	<context:property-placeholder location="classpath*:*/*.properties" />

	<dubbo:protocol name="dubbo" port="20882"></dubbo:protocol>
	<dubbo:application name="pinyougou-search-service" />
	<dubbo:registry address="zookeeper://192.168.25.128:2181" />
	<dubbo:annotation package="com.pinyougou.search.service.impl" />


</beans>


applicationContext-solr.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:solr="http://www.springframework.org/schema/data/solr"
	xsi:schemaLocation="http://www.springframework.org/schema/data/solr 
  		http://www.springframework.org/schema/data/solr/spring-solr-1.0.xsd
		http://www.springframework.org/schema/beans 
		http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context 
		http://www.springframework.org/schema/context/spring-context.xsd">
	<!-- solr服务器地址 -->
	<solr:solr-server id="solrServer" url="http://192.168.25.128:8080/solr" />
	<!-- solr模板,使用solr模板可对索引库进行CRUD的操作 -->
	<bean id="solrTemplate" class="org.springframework.data.solr.core.SolrTemplate">
		<constructor-arg ref="solrServer" />
	</bean>
</beans>


applicationContext-tx.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:tx="http://www.springframework.org/schema/tx"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc 
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
		http://www.springframework.org/schema/tx 
		http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context.xsd">
 

    <!-- 事务管理器  -->  
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
        <property name="dataSource" ref="dataSource" />  
    </bean>  
      
    <!-- 开启事务控制的注解支持 -->  
    <tx:annotation-driven transaction-manager="transactionManager"/>
   
</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"
	version="2.5">
	<display-name>pinyougou-search-service</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>

	<!-- 加载spring容器 -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath*:spring/applicationContext*.xml</param-value>
	</context-param>
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
</web-app>


3、创建pinyougou-search-web


(1)、创建war包子模块




(2)、加入依赖


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>com.pinyougou</groupId>
		<artifactId>pinyougou-parent</artifactId>
		<version>0.0.1-SNAPSHOT</version>
	</parent>
	<artifactId>pinyougou-search-web</artifactId>
	<packaging>war</packaging>

	<dependencies>
		<dependency>
			<groupId>com.pinyougou</groupId>
			<artifactId>pinyougou-common</artifactId>
			<version>0.0.1-SNAPSHOT</version>
		</dependency>
		<dependency>
			<groupId>com.pinyougou</groupId>
			<artifactId>pinyougou-search-interface</artifactId>
			<version>0.0.1-SNAPSHOT</version>
		</dependency>

		<!-- Spring -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-beans</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aspects</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jms</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context-support</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
		</dependency>
		<!-- dubbo相关 -->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>dubbo</artifactId>
		</dependency>
		<dependency>
			<groupId>org.apache.zookeeper</groupId>
			<artifactId>zookeeper</artifactId>
		</dependency>
		<dependency>
			<groupId>com.github.sgroschupf</groupId>
			<artifactId>zkclient</artifactId>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
		</dependency>
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
		</dependency>
		<dependency>
			<groupId>javassist</groupId>
			<artifactId>javassist</artifactId>
		</dependency>
		<dependency>
			<groupId>commons-codec</groupId>
			<artifactId>commons-codec</artifactId>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<scope>provided</scope>
		</dependency>

		<!-- 分页插件相关 -->
		<dependency>
			<groupId>com.github.pagehelper</groupId>
			<artifactId>pagehelper</artifactId>
		</dependency>
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis</artifactId>
		</dependency>

		<!-- spring-data-solr相关jar -->
		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-solr</artifactId>
			<version>1.5.5.RELEASE</version>
		</dependency>
	</dependencies>


	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.tomcat.maven</groupId>
				<artifactId>tomcat7-maven-plugin</artifactId>
				<version>2.2</version>
				<configuration>
					<!-- 指定端口 -->
					<port>8081</port>
					<!-- 请求路径 -->
					<path>/</path>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>


(3)、加入配置文件




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:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc 
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://code.alibabatech.com/schema/dubbo 
        http://code.alibabatech.com/schema/dubbo/dubbo.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context.xsd">
	<context:property-placeholder location="classpath:*/*.properties" />

	<mvc:annotation-driven>
		<mvc:message-converters register-defaults="true">
			<bean
				class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
				<property name="supportedMediaTypes" value="application/json" />
				<property name="features">
					<array>
						<value>WriteMapNullValue</value>
						<value>WriteDateUseDateFormat</value>
					</array>
				</property>
			</bean>
		</mvc:message-converters>
	</mvc:annotation-driven>

	<!-- 引用dubbo 服务 -->
	<dubbo:application name="pinyougou-search-web" />
	<dubbo:registry address="zookeeper://192.168.25.128:2181" />
	<dubbo:annotation package="com.pinyougou.search.controller" />
	<!-- 配置消费者链接服务的超时时间 -->
	<dubbo:consumer timeout="400000" />

</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"
	version="2.5">
	<display-name>pinyougou-search-web</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>

	<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>
		<init-param>
			<param-name>forceEncoding</param-name>
			<param-value>true</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>CharacterEncodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	<servlet>
		<servlet-name>springmvc</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:spring/*.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>springmvc</servlet-name>
		<url-pattern>*.do</url-pattern>
	</servlet-mapping>
</web-app>


四、搭建项目进行solr数据初始化


1、创建jar工程




2、导入依赖


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>com.pinyougou</groupId>
		<artifactId>pinyougou-parent</artifactId>
		<version>0.0.1-SNAPSHOT</version>
	</parent>
	<artifactId>pinyougou-pojo</artifactId>
	<dependencies>
		<!-- 加入spring-data-solr依赖 -->
		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-solr</artifactId>
			<version>1.5.5.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
		</dependency>
	</dependencies>
</project>


3、在pinyougou-pojo项目中spring-data-solr依赖,并在TbItem.java中加入属性字段与域字段对应的注解


pom.xml


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>com.pinyougou</groupId>
		<artifactId>pinyougou-parent</artifactId>
		<version>0.0.1-SNAPSHOT</version>
	</parent>
	<artifactId>pinyougou-pojo</artifactId>
	<dependencies>
		<!-- 加入spring-data-solr依赖 -->
		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-solr</artifactId>
			<version>1.5.5.RELEASE</version>
		</dependency>
	</dependencies>
</project>


TbItem.java


package com.pinyougou.pojo;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Map;

import org.apache.solr.client.solrj.beans.Field;
import org.springframework.data.solr.core.mapping.Dynamic;

public class TbItem implements Serializable {

	/**
	 * Field注解用于属性和solr中的域字段对应
	 */
	@Field("id")
	private Long id;

	@Field("item_title")
	private String title;

	private String sellPoint;

	@Field("item_price")
	private BigDecimal price;

	private Integer stockCount;

	private Integer num;

	private String barcode;

	@Field("item_image")
	private String image;

	private Long categoryid;

	private String status;

	private Date createTime;

	private Date updateTime;

	private String itemSn;

	private BigDecimal costPirce;

	private BigDecimal marketPrice;

	private String isDefault;

	@Field("item_goodsid")
	private Long goodsId;

	private String sellerId;

	private String cartThumbnail;

	@Field("item_category")
	private String category;

	@Field("item_brand")
	private String brand;

	private String spec; // {"网络":"移动4G","机身内存":"64G"}

	@Field("item_seller")
	private String seller;

	/**
	 * 动态域字段的写法与注解
	 * 该字段是用来进行转换为json格式的时候进行存储查询出的数据的字段
	 */
	@Dynamic
	@Field("item_spec_*")
	private Map<String, String> specMap;

	// 省略set/get方法。。。
}


4、编写配置文件


applicaationContext-solr.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:solr="http://www.springframework.org/schema/data/solr"
	xsi:schemaLocation="http://www.springframework.org/schema/data/solr 
  		http://www.springframework.org/schema/data/solr/spring-solr-1.0.xsd
		http://www.springframework.org/schema/beans 
		http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context 
		http://www.springframework.org/schema/context/spring-context.xsd">
	<!-- solr服务器地址 -->
	<solr:solr-server id="solrServer" url="http://192.168.25.128:8080/solr" />
	<!-- solr模板,使用solr模板可对索引库进行CRUD的操作 -->
	<bean id="solrTemplate" class="org.springframework.data.solr.core.SolrTemplate">
		<constructor-arg ref="solrServer" />
	</bean>
</beans>


5、TbItemMapper接口以及映射文件


	List<TbItem> selectAllGrounding();


	<!-- 查询已经上架的商品集合 -->
	<select id="selectAllGrounding" resultMap="BaseResultMap">
		select item.* from tb_item item , tb_goods goods where item.goods_id=goods.id and goods.audit_status='2'
	</select>


5、编写测试类进行solr数据初始化


import java.util.List;
import java.util.Map;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.solr.core.SolrTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.alibaba.fastjson.JSON;
import com.pinyougou.mapper.TbItemMapper;
import com.pinyougou.pojo.TbItem;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath*:spring/applicationContext*.xml" })
public class SlorManager {

	@Autowired
	private SolrTemplate solrTemplate;

	@Autowired
	private TbItemMapper itemMapper;

	/**
	 * 将数据库中的item表中数据导入solr索引库
	 */
	@Test
	public void testAdd() {
		List<TbItem> list = itemMapper.selectAllGrounding();
		for (TbItem tbItem : list) {
			String spec = tbItem.getSpec();
			Map<String, String> specMap = JSON.parseObject(spec, Map.class);
			tbItem.setSpecMap(specMap);
		}
		solrTemplate.saveBeans(list);
		solrTemplate.commit();

	}

}


五、完成关键字搜索并高亮显示的功能


1、将静态资源导入search-web项目中


将网站前台静态资源以及search.html页面导入search-web项目的webapp下


2、加入angularjs的过滤器




        该过滤器作用是将后台传递的带有html标签的数据按照html的解析方式输出,此处主要用来让高亮字段的html标签被解析成html的数据进行高亮显示


//定义过滤器,处理字符串为HTML标签
//使用方式:<em ng-bind-html="带标签的数据 | trustHtml"></em>
app.filter("trustHtml",function($sce){
	return function(data){
		return $sce.trustAsHtml(data);
	};
});


3、改造search.html




4、base.js


//定义模块
var app = angular.module("pinyougou", []);


5、searchController.js


//定义控制器
app.controller("searchController", function($scope,searchService) {
	
	$scope.search = function(){
		
		//调用service查询数据
		searchService.search($scope.paramMap).success(function(data){
			$scope.resultMap = data;
		});
	}
});


6、searchService.js


/*搜索的service层代码*/
app.service("searchService", function($http){
	
	//搜索的方法
	this.search = function(paramMap){
		return $http.post("./itemSearch/search.do", paramMap);
	}
});


7、ItemSearchController.java


package com.pinyougou.search.controller;

import java.util.Map;

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

import com.alibaba.dubbo.config.annotation.Reference;
import com.pinyougou.search.service.ItemSearchService;

@RestController
@RequestMapping("/itemSearch")
public class ItemSearchController {
	
	@Reference
	private ItemSearchService searchService;
	
	@RequestMapping("/search.do")
	public Map search(@RequestBody Map<String, String> paramMap){
		return searchService.search(paramMap);
	}
}


8、ItemSearchServiceImpl.java


package com.pinyougou.search.service.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.solr.core.SolrTemplate;
import org.springframework.data.solr.core.query.Criteria;
import org.springframework.data.solr.core.query.HighlightOptions;
import org.springframework.data.solr.core.query.HighlightQuery;
import org.springframework.data.solr.core.query.SimpleHighlightQuery;
import org.springframework.data.solr.core.query.result.HighlightEntry.Highlight;
import org.springframework.data.solr.core.query.result.HighlightPage;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.pinyougou.pojo.TbItem;
import com.pinyougou.search.service.ItemSearchService;

@Service
@Transactional
public class ItemSearchServiceImpl implements ItemSearchService {

	@Autowired
	private SolrTemplate solrTemplate;
	
	@Override
	public Map search(Map<String, String> paramMap) {
		
		//使用高亮查询
		//1.创建高亮查询对象
		HighlightQuery query = new SimpleHighlightQuery();
		//2.创建普通查询条件,将对象放入高亮查询对象中
		Criteria criteria = new Criteria("item_title").contains(paramMap.get("keywords"));
		query.addCriteria(criteria);
		//3.设置高亮属性
		HighlightOptions highlightOptions = new HighlightOptions();
			//a. 指定高亮显示的域字段
		highlightOptions.addField("item_title");
			//b. 设置前缀和后缀
		highlightOptions.setSimplePrefix("<span style=\"color:red\">");
		highlightOptions.setSimplePostfix("</span>");
		//4.将高亮属性放入查询对象中
		query.setHighlightOptions(highlightOptions);
		//5.执行查询操作
		HighlightPage<TbItem> highlightPage = solrTemplate.queryForHighlightPage(query, TbItem.class);
		//查询出的高亮属性的格式
		System.out.println(JSON.toJSONString(highlightPage, SerializerFeature.DisableCircularReferenceDetect));
		//6.获取结果中的content
		List<TbItem> content = highlightPage.getContent();
		//7.循环遍历对象结果集
		for (TbItem item : content) {
			//根据实体类获取对应的高亮结果集
			List<Highlight> highlights = highlightPage.getHighlights(item);
			if(highlights != null && highlights.size() > 0) {
				item.setTitle(highlights.get(0).getSnipplets().get(0));
			}
		}
		//8.将查询的对象结果集放入返回值集合中
		Map resultMap = new HashMap<>();
		resultMap.put("list", content);
		resultMap.put("total", highlightPage.getTotalElements());
		return resultMap;
	}

}


六、实现商家上下架solr索引库数据的同步更新


1、shop-web项目中引入search-service


2、修改shop-web中GoodsController.java代码




3、ItemSearchServiceImpl.java


	@Autowired
	private TbItemMapper itemMapper;

	/**
	 * 根据商品id进行索引库数据的添加操作
	 */
	public void saveItemsByGoodsIds(Long[] selectIds) {

		// 根据商品id查询出item集合
		TbItemExample example = new TbItemExample();
		List<Long> goodsIds = new ArrayList<Long>();
		for (Long id : selectIds) {
			goodsIds.add(id);
		}
		example.createCriteria().andGoodsIdIn(goodsIds);
		List<TbItem> itemList = itemMapper.selectByExample(example);

		// 将数据保存在solr索引库中
		solrTemplate.saveBeans(itemList);
		solrTemplate.commit();
	}

	/**
	 * 根据商品id删除索引库中的数据
	 */
	public void delItemsByGoodsIds(Long[] selectIds) {
		List<String> goodsIds = new ArrayList<String>();
		for (Long id : selectIds) {
			goodsIds.add(id+"");
		}
		//删除索引库中的数据
		SolrDataQuery query = new SimpleQuery();
		Criteria criteria = new Criteria("item_goodsid").in(goodsIds);
		query.addCriteria(criteria);
		solrTemplate.delete(query);
		solrTemplate.commit();
	}


七、实现从门户网站点击搜索按钮跳转到搜索系统进行搜索


1、portal-web的index.html页面搜索框改造




2、portal-web中的indexController.js


	//搜索按钮触发的事件
	$scope.search = function(){
		if($scope.keywords != null && $scope.keywords != ''){
			//使用angularjs跳转方式需要加 # 号
			location.href = "http://search.pinyougou.com/search.html#?keywords=" + $scope.keywords;
		}
	}


3、search-web项目的searchController.js




4、search.html添加init方法




八、实现进入search.html进行分类和品牌数据的查询显示并缓存


1、初始化品牌数据和规格数据并缓存入redis


(1)、solr-data-init项目中引入pinyougou-common的依赖(为了使用redis的配置)


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>com.pinyougou</groupId>
		<artifactId>pinyougou-parent</artifactId>
		<version>0.0.1-SNAPSHOT</version>
	</parent>
	<artifactId>solr-data-init</artifactId>

	<dependencies>
		<dependency>
			<groupId>com.pinyougou</groupId>
			<artifactId>pinyougou-dao</artifactId>
			<version>0.0.1-SNAPSHOT</version>
		</dependency>

		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-solr</artifactId>
			<version>1.5.5.RELEASE</version>
		</dependency>

		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
		</dependency>

		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>1.2.28</version>
		</dependency>
		<dependency>
			<groupId>com.pinyougou</groupId>
			<artifactId>pinyougou-common</artifactId>
			<version>0.0.1-SNAPSHOT</version>
		</dependency>
	</dependencies>
</project>


(2)、编写初始化redis数据的测试类


package com.pinyougou.initdata;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.alibaba.fastjson.JSON;
import com.pinyougou.mapper.TbItemCatMapper;
import com.pinyougou.mapper.TbSpecificationOptionMapper;
import com.pinyougou.mapper.TbTypeTemplateMapper;
import com.pinyougou.pojo.TbItemCat;
import com.pinyougou.pojo.TbSpecificationOption;
import com.pinyougou.pojo.TbSpecificationOptionExample;
import com.pinyougou.pojo.TbTypeTemplate;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath*:spring/applicationContext-*.xml"})
public class RedisMananger {

	@Autowired
	private TbItemCatMapper itemCatMapper;
	
	@Autowired
	private TbTypeTemplateMapper templateMapper;
	
	@Autowired
	private RedisTemplate redisTemplate;
	
	@Autowired
	private TbSpecificationOptionMapper specOptionMapper;
	
	/**
	 * 初始化品牌数据
	 */
	@Test
	public void initBrandList() {
		//查询所有分类列表
		List<TbItemCat> itemCatList = itemCatMapper.selectByExample(null);
		for (TbItemCat itemCat : itemCatList) {
			//根据分类id查询模板列表
			TbTypeTemplate typeTemplate = templateMapper.selectByPrimaryKey(itemCat.getTypeId());
			if(typeTemplate != null) {
				String brandIds = typeTemplate.getBrandIds();//[{"id":27, "text":"华为"},{"id":27, "text":"华为"}]
				//转为json获取text的数据
				List<Map> brandList = JSON.parseArray(brandIds, Map.class);
				List<String> brands = new ArrayList<String>();
				for (Map brand : brandList) {
					brands.add(brand.get("text") + "");
				}
				//将数据添加到redis缓存中
				redisTemplate.boundHashOps("brandList").put(itemCat.getName(), brands);
				
				//获取规格数据,并缓存的奥redis中
				//将[{id:xxx, text:xxx}]数据变为:[{id:xxx, text:xxx, options:[{id:xxx, optionName:xxx}]}]
				String specIds = typeTemplate.getSpecIds(); 
				List<Map> specMap = JSON.parseArray(specIds, Map.class);
				for (Map map : specMap) {
					TbSpecificationOptionExample example = new TbSpecificationOptionExample();
					example.createCriteria().andSpecIdEqualTo(Long.parseLong(map.get("id") + ""));
					List<TbSpecificationOption> optionList = specOptionMapper.selectByExample(example);
					map.put("options", optionList);
				}
				//将数据出入redis集合中
				redisTemplate.boundHashOps("specList").put(itemCat.getName(), specMap);
			}
		}
	}
	
	/**
	 * 测试是否能获取到数据
	 */
	@Test
	public void testGet() {
		System.out.println(redisTemplate.boundHashOps("brandList").get("手机"));;
	}
}


2、实现查询页面显示分类数据、品牌数据、规格数据


(1)、ItemSearchServiceImpl.java中添加获取分类数据、品牌数据、规格数据的代码


	@Autowired
	private RedisTemplate redisTemplate;

	/**
	 * 查询结果集
	 * 
	 * @param paramMap
	 * @return
	 */
	public Map search(Map<String, String> paramMap) {

		// 创建返回结果集
		Map<String, Object> resultMap = new HashMap<>();

		// 获取分类数据开始-----------------------------------------------------------------------------------------
		Query groupQuery = new SimpleQuery();
		// 查询复制域
		groupQuery.addCriteria(new Criteria("item_keywords").is(paramMap.get("keywords")));
		// 设置分组属性
		GroupOptions groupOptions = new GroupOptions();
		// 设置分组域字段名称
		groupOptions.addGroupByField("item_category");
		groupQuery.setGroupOptions(groupOptions);
		// 执行分组查询,使用queryForGroupPage
		GroupPage<TbItem> groupPage = solrTemplate.queryForGroupPage(groupQuery, TbItem.class);
		// 获取分组结果,并处理结果集
		GroupResult<TbItem> groupResult = groupPage.getGroupResult("item_category");
		Page<GroupEntry<TbItem>> groupEntries = groupResult.getGroupEntries();
		List<GroupEntry<TbItem>> groupContent = groupEntries.getContent();
		// 创建集合用来存放分类数据
		List<String> categoryList = new ArrayList<String>();
		for (GroupEntry<TbItem> groupEntry : groupContent) {
			categoryList.add(groupEntry.getGroupValue());
		}
		// 将分类数据放入返回结果集
		resultMap.put("categoryList", categoryList);
		// 获取分类数据结束-----------------------------------------------------------------------------------------
		

		// 获取品牌数据开始=========================================================================================
		if (categoryList != null && categoryList.size() > 0) {
			// 从redis中获取第一个分类下的所有品牌数据
			List<String> brandList = (List<String>) redisTemplate.boundHashOps("brandList").get(categoryList.get(0));
			// 将数据放入结果集
			resultMap.put("brandList", brandList);
		}
		// 获取品牌数据结束=========================================================================================
		

		// 获取规格数据开始#########################################################################################
		if (categoryList != null && categoryList.size() > 0) {
			List<Map> sepcMap = (List<Map>) redisTemplate.boundHashOps("specList").get(categoryList.get(0));
			// 将数据放入结果集
			resultMap.put("specList", sepcMap);
		}
		// 获取规格数据结束#########################################################################################
		

		// 使用高亮查询开始*****************************************************************************************
		// 1.创建高亮查询对象
		HighlightQuery query = new SimpleHighlightQuery();
		// 2.创建普通查询条件,将对象放入高亮查询对象中
		Criteria criteria = new Criteria("item_keywords").is(paramMap.get("keywords"));
		query.addCriteria(criteria);
		// 3.设置高亮属性
		HighlightOptions highlightOptions = new HighlightOptions();
			// a. 指定高亮显示的域字段
		highlightOptions.addField("item_title");
			// b. 设置前缀和后缀
		highlightOptions.setSimplePrefix("<span style=\"color:red\">");
		highlightOptions.setSimplePostfix("</span>");
		// 4.将高亮属性放入查询对象中
		query.setHighlightOptions(highlightOptions);
		// 5.执行查询操作
		HighlightPage<TbItem> highlightPage = solrTemplate.queryForHighlightPage(query, TbItem.class);
		// 查询出的高亮属性的格式
		System.out.println(JSON.toJSONString(highlightPage, SerializerFeature.DisableCircularReferenceDetect));
		// 6.获取结果中的content
		List<TbItem> content = highlightPage.getContent();
		// 7.循环遍历对象结果集
		for (TbItem item : content) {
			// 根据实体类获取对应的高亮结果集
			List<Highlight> highlights = highlightPage.getHighlights(item);
			if (highlights != null && highlights.size() > 0) {
				item.setTitle(highlights.get(0).getSnipplets().get(0));
			}
		}
		// 使用高亮查询结束*****************************************************************************************

		// 8.将查询的对象结果集放入返回值集合中
		resultMap.put("list", content);
		resultMap.put("total", highlightPage.getTotalElements());
		return resultMap;
	}


(2)、改造search.html中显示分类、品牌、规格的代码




3、完善ItemSearchServiceImpl.java代码中的其他查询条件


(1)、完善search.html中的查询条件




(2)、searchController.js


//定义控制器
app.controller("searchController", function($scope, $location, searchService) {
	
	//初始化查询参数对象:分类、品牌、价格、排序、页码、规格
	$scope.paramMap = {category:'', brand:'', price:'', order:'ASC', pageNo:1, spec:{}};
	
	//添加查询条件的函数
	$scope.addParamToParamMap = function(key, value){
		if(key == 'pageNo' && value < 0){
			return;
		}
		$scope.paramMap[key] = value;
		//调用查询方法
		$scope.search();
	}

	$scope.deleteSpecParamToMap=function(key){
		delete $scope.paramMap.spec[key];
		$scope.search();
	}
	
	//进入search.html时触发的方法
	$scope.init = function(){
		//获取其他页面跳转到本系统时的参数
		$scope.paramMap['keywords'] = $location.search()['keywords'];
		// alert($scope.paramMap['keywords']);
		//将其他页面传递的关键字赋值给keywords
		$scope.keywords = $location.search()['keywords'];
		$scope.search();
	}
	
	//点击搜索框触发的事件
	$scope.searchKeywords = function(){
		//清空其他查询条件
		$scope.paramMap = {category:'', brand:'', price:'', order:'ASC', pageNo:1, spec:{}};
		$scope.paramMap['keywords'] = $scope.keywords;
		$scope.search();
	}
	
	//真正执行查询的方法
	$scope.search = function(){
		//调用service查询数据
		searchService.search($scope.paramMap).success(function(data){
			$scope.resultMap = data;
			$scope.totalPages = [];
			for (var i = 0; i < data.totalPage; i++) {
				$scope.totalPages.push(i + 1);
			}
		});
	}
});


(2)、完善ItemSearchServiceImpl.java中过滤条件查询代码




	/**
	 * 查询结果集
	 * 
	 * @param paramMap
	 * @return
	 */
	public Map search(Map<String, Object> paramMap) {

		// 创建返回结果集
		Map<String, Object> resultMap = new HashMap<>();

		// 获取分类数据开始-----------------------------------------------------------------------------------------
		Query groupQuery = new SimpleQuery();
		// 查询复制域
		groupQuery.addCriteria(new Criteria("item_keywords").is(paramMap.get("keywords")));
		// 设置分组属性
		GroupOptions groupOptions = new GroupOptions();
		// 设置分组域字段名称
		groupOptions.addGroupByField("item_category");
		groupQuery.setGroupOptions(groupOptions);
		// 执行分组查询,使用queryForGroupPage
		GroupPage<TbItem> groupPage = solrTemplate.queryForGroupPage(groupQuery, TbItem.class);
		// 获取分组结果,并处理结果集
		GroupResult<TbItem> groupResult = groupPage.getGroupResult("item_category");
		Page<GroupEntry<TbItem>> groupEntries = groupResult.getGroupEntries();
		List<GroupEntry<TbItem>> groupContent = groupEntries.getContent();
		// 创建集合用来存放分类数据
		List<String> categoryList = new ArrayList<String>();
		for (GroupEntry<TbItem> groupEntry : groupContent) {
			categoryList.add(groupEntry.getGroupValue());
		}
		// 将分类数据放入返回结果集
		resultMap.put("categoryList", categoryList);
		// 获取分类数据结束-----------------------------------------------------------------------------------------
		

		// 获取品牌数据开始=========================================================================================
		if (categoryList != null && categoryList.size() > 0) {
			// 从redis中获取第一个分类下的所有品牌数据
			List<String> brandList = (List<String>) redisTemplate.boundHashOps("brandList").get(categoryList.get(0));
			// 将数据放入结果集
			resultMap.put("brandList", brandList);
		}
		// 获取品牌数据结束=========================================================================================
		

		// 获取规格数据开始#########################################################################################
		if (categoryList != null && categoryList.size() > 0) {
			List<Map> sepcMap = (List<Map>) redisTemplate.boundHashOps("specList").get(categoryList.get(0));
			// 将数据放入结果集
			resultMap.put("specList", sepcMap);
		}
		// 获取规格数据结束#########################################################################################
		

		// 使用高亮查询开始*****************************************************************************************
		// 1.创建高亮查询对象
		HighlightQuery query = new SimpleHighlightQuery();
		// 2.创建查询条件,将对象放入高亮查询对象中
			// a.普通查询条件,关键字查询
		Criteria criteria = new Criteria("item_keywords").is(paramMap.get("keywords"));
		query.addCriteria(criteria);
		
			// b.构建其他过滤查询条件(价格区间、品牌、分类、规格、排序、分页等)
		FilterQuery filterQuery = new SimpleFilterQuery();
			// 分类条件
		if(paramMap.get("category") != null && !paramMap.get("category").equals("")) {
			filterQuery.addCriteria(new Criteria("item_category").is(paramMap.get("category")));
		}
			// 品牌条件
		if(paramMap.get("brand") != null && !paramMap.get("brand").equals("")) {
			filterQuery.addCriteria(new Criteria("item_brand").is(paramMap.get("brand")));
		}
			// 规格条件
		Map<String, String> specMap = (Map<String, String>) paramMap.get("spec");
		for (String key : specMap.keySet()) {
			filterQuery.addCriteria(new Criteria("item_spec_" + key).is(specMap.get(key)));
		}
			// 价格条件
		if(paramMap.get("price") != null && !paramMap.get("price").equals("")) {
			String[] price = (paramMap.get("price") + "").split("-");
			if(!"*".equals(price[1])) {
				filterQuery.addCriteria(new Criteria("item_price").between(price[0], price[1], true, true));
			}else {
				filterQuery.addCriteria(new Criteria("item_price").greaterThanEqual(price[0]));
			}
		}
		
			// c.将过滤查询条件放入查询对象中
		query.addFilterQuery(filterQuery);
			// d.将排序条件放入查询对象中
		if(paramMap.get("order").equals("ASC")) {
			query.addSort(new Sort(Direction.ASC, "item_price"));
		}else {
			query.addSort(new Sort(Direction.DESC, "item_price"));
		}
			// e.分页显示数据
		int pageNo = (int) paramMap.get("pageNo");
		query.setOffset((pageNo - 1) * 60);	//起始位置
		query.setRows(60); //每页显示60条
		
		// 3.设置高亮属性
		HighlightOptions highlightOptions = new HighlightOptions();
			// a. 指定高亮显示的域字段
		highlightOptions.addField("item_title");
			// b. 设置前缀和后缀
		highlightOptions.setSimplePrefix("<span style=\"color:red\">");
		highlightOptions.setSimplePostfix("</span>");
		// 4.将高亮属性放入查询对象中
		query.setHighlightOptions(highlightOptions);
		// 5.执行查询操作
		HighlightPage<TbItem> highlightPage = solrTemplate.queryForHighlightPage(query, TbItem.class);
		// 查询出的高亮属性的格式
		System.out.println(JSON.toJSONString(highlightPage, SerializerFeature.DisableCircularReferenceDetect));
		// 6.获取结果中的content
		List<TbItem> content = highlightPage.getContent();
		// 7.循环遍历对象结果集
		for (TbItem item : content) {
			// 根据实体类获取对应的高亮结果集
			List<Highlight> highlights = highlightPage.getHighlights(item);
			if (highlights != null && highlights.size() > 0 && highlights.get(0).getSnipplets() != null && highlights.get(0).getSnipplets().size() > 0) {
				
				item.setTitle(highlights.get(0).getSnipplets().get(0));
			}
		}
		// 使用高亮查询结束*****************************************************************************************

		// 8.将查询的对象结果集放入返回值集合中
		resultMap.put("list", content);
		resultMap.put("total", highlightPage.getTotalElements());
		resultMap.put("totalPage", highlightPage.getTotalPages());
		return resultMap;
	}


4、完善search.html页面点击查询条件后的面包屑以及查询条件的隐藏


(1)、search.html




(2)、searchController.js


	//添加查询条件的函数
	$scope.addParamToParamMap = function(key, value){
		if(key == 'pageNo' && value < 0){
			return;
		}
		$scope.paramMap[key] = value;
		//调用查询方法
		$scope.search();
	}
	$scope.addSpecParamToMap = function(key, value){
		$scope.paramMap.spec[key] = value;
		$scope.search();
	}
	
	//从参数中移除查询条件
	$scope.delParamFromPramMap = function(key){
		$scope.paramMap[key] = '';
		$scope.search();
	}
	$scope.delSpecParamFromPramMap = function(key){
		delete $scope.paramMap.spec[key];
		$scope.search();
	}


猜你喜欢

转载自blog.csdn.net/wingzhezhe/article/details/80670708
今日推荐