Spring-4.x+Solr-4.10.3+spring-data-solr-1.5.5.RELEASE整合配置

阶段一:相关链接

阶段二:整合配置

  • pom.xml依赖
<dependencies>
        <!-- Spring配置 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>4.3.19.RELEASE</version>
        </dependency>

        <!--Junit-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>

        <!--Lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.8</version>
        </dependency>

        <!--Spring Data Solr-->
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-solr</artifactId>
            <version>1.5.5.RELEASE</version>
        </dependency>
    </dependencies>
  • spring-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:solr="http://www.springframework.org/schema/data/solr"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
		http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/data/solr http://www.springframework.org/schema/data/solr/spring-solr.xsd">

    <!-- 单机solr服务器地址 -->
    <!--
    <solr:solr-server id="solrServer" url="http://192.168.44.121:8080/solr"/>
    -->

    <!-- SolrCloud集群配置环境-->
    <bean id="solrServer" class="org.apache.solr.client.solrj.impl.CloudSolrServer">
        <!--ZK注册中心【】-->
        <constructor-arg value="192.168.44.110:2181,192.168.44.111:2181,192.168.44.112:2181"/>

        <!--默认的Collection-->
        <property name="defaultCollection" value="collection1"/>
    </bean>


    <!-- solr模板,使用solr模板可对索引库进行CRUD的操作 -->
    <bean id="solrTemplate" class="org.springframework.data.solr.core.SolrTemplate">
        <constructor-arg ref="solrServer"/>
    </bean>
</beans>

阶段三:Solr域配置

  • 编辑schema.xml文件配置域信息
<!-- 配置域【普通搜索】 -->
<field name="emp_id" type="long" indexed="true" stored="true"/>
<field name="emp_userName" type="string" indexed="true" stored="true" />
<field name="emp_nickName" type="text_ik" indexed="true" stored="true"/>
<field name="emp_avatar" type="string" indexed="true" stored="true" />
<field name="emp_describe" type="text_ik" indexed="true" stored="true" />
<field name="emp_occupation" type="text_ik" indexed="true" stored="true" />
<field name="emp_salary" type="double" indexed="true" stored="true"/>
<field name="emp_updTime" type="date" indexed="true" stored="true"/>

<!-- 复制域【关键字】 -->
<field name="emp_keywords" type="text_ik" indexed="true" stored="false" multiValued="true"/>
<copyField source="emp_userName" dest="emp_keywords"/>
<copyField source="emp_nickName" dest="emp_keywords"/>
<copyField source="emp_describe" dest="emp_keywords"/>
<copyField source="emp_occupation" dest="emp_keywords"/>

<!-- 动态域【技能搜索】 -->
<dynamicField name="emp_skill_*" type="string" indexed="true" stored="true" />

在这里插入图片描述

阶段四:SolrTemplate相关操作

  • Employee实体
package com.hf.solr.entity;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import lombok.experimental.Accessors;
import org.apache.solr.client.solrj.beans.Field;
import org.springframework.data.solr.core.mapping.Dynamic;

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

/**
 * @Copyright (C), 2017-2019
 * @FileName: TBUser
 * @Author: hf
 * @Date: 2019/9/23 18:25
 * @Description: 【雇员实体类】
 */
@Getter
@Setter
@Accessors(chain = true)
@ToString
public class Employee implements Serializable {

    //id
    @Field("id")
    private long id;

    //雇员名
    @Field("emp_userName")
    private String userName;

    //昵称
    @Field("emp_nickName")
    private String nickName;

    //头像
    @Field("emp_avatar")
    private String avatar;

    //个人描述
    @Field("emp_describe")
    private String describe;

    //职位
    @Field("emp_occupation")
    private String occupation;

    //薪资
    @Field("emp_salary")
    private double salary;

    //技能及描述
    @Field("emp_skill_*")
    @Dynamic
    private Map<String, String> skillMap;

    //入职时间
    @Field("emp_updTime")
    private Date updTime;

}

  • CRUD相关
package com.hf.solr;

import com.hf.solr.entity.Employee;
import org.apache.commons.lang3.StringUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.solr.core.SolrTemplate;
import org.springframework.data.solr.core.query.*;
import org.springframework.data.solr.core.query.result.HighlightEntry;
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 java.util.*;

/**
 * @Copyright (C), 2017-2019
 * @FileName: TestSolrTemplate
 * @Author: hf
 * @Date: 2019/9/23 18:20
 * @Description: 【测试Solr相关操作】
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:spring-solr.xml")
public class TestSolrTemplate {

    @Autowired
    private SolrTemplate solrTemplate;


    //solr高级搜索过滤
    @Test
    public void SolrAdvancedSearch() {
        HashMap<String, Object> map = new HashMap<>();
        //关键字
        map.put("keywords", "张三的座右铭是莫等闲");
        //人员名称
        map.put("userName", "张三");
        //职位
        map.put("occupation", "");

        //薪资区间
        map.put("salary", "7852_27354");

        //排序ASC DESC
        map.put("sort", "DESC");

        //排序字段
        map.put("sortField", "salary");

        //分页
        map.put("pageNum", 1);
        map.put("pageSize", 20);

        //技能及描述
        HashMap<String, String> skMap = new HashMap<>();
        skMap.put("Java", "框架");
        map.put("skillMap", skMap);

        //获取查询结果集
        HashMap<String, Object> resMap = searchList(map);
        System.out.println("总页数:" + resMap.get("totalPages"));
        System.out.println("总条数:" + resMap.get("total"));
        List<Employee> list = (List<Employee>) resMap.get("rows");
        for (Employee employee : list) {
            System.out.println(employee);
        }

    }
    
    /**
     * 功能描述:
     * 〈
     * Solr 高级搜索过滤
     * 〉
     *
     * @className: TestSolrTemplate
     * @author: hf
     * @version: 1.0.0
     * @date: 2019/9/24 17:23
     * @param: [searchMap 【搜索条件集合】]
     * @return: java.util.HashMap
     */
    private HashMap<String, Object> searchList(Map<String, Object> searchMap) {
        HashMap<String, Object> map = new HashMap<>();
        //高亮选项初始化
        SimpleHighlightQuery query = new SimpleHighlightQuery();

        //构建高亮选项对象
        HighlightOptions highlightOptions = new HighlightOptions().addField("emp_userName");
        highlightOptions.setSimplePrefix("<em style='color:red'>");
        highlightOptions.setSimplePostfix("</em>");

        //为查询对象设置高亮选项
        query.setHighlightOptions(highlightOptions);

        //1.1 【关键字】查询
        Criteria criteria = new Criteria("emp_keywords").is(searchMap.get("keywords"));
        query.addCriteria(criteria);

        //1.2 按照【雇员们】名过滤
        if (StringUtils.isNotBlank((String) searchMap.get("userName"))) {
            FilterQuery filterQuery = new SimpleFilterQuery();
            Criteria filterCriteria = new Criteria("emp_userName").is((String) searchMap.get("userName"));
            filterQuery.addCriteria(filterCriteria);
            query.addFilterQuery(filterQuery);
        }

        //1.3 按照【职位】过滤
        if (StringUtils.isNotBlank((String) searchMap.get("occupation"))) {
            FilterQuery filterQuery = new SimpleFilterQuery();
            Criteria filterCriteria = new Criteria("emp_occupation").is((String) searchMap.get("emp_occupation"));
            filterQuery.addCriteria(filterCriteria);
            query.addFilterQuery(filterQuery);
        }

        //1.4 按照【技能及描述动态】过滤
        if (null != searchMap.get("skillMap")) {
            //获取技能组
            Map<String, String> specMap = (Map<String, String>) searchMap.get("skillMap");
            for (String key : specMap.keySet()) {
                FilterQuery filterQuery = new SimpleFilterQuery();
                Criteria filterCriteria = new Criteria("emp_skill_" + key).is((String) searchMap.get(key));
                filterQuery.addCriteria(filterCriteria);
                query.addFilterQuery(filterQuery);
            }
        }

        //1.5 按照【薪资区间】过滤
        if (StringUtils.isNotBlank((String) searchMap.get("salary"))) {
            String[] price = ((String) searchMap.get("salary")).split("_");
            //下限处理 0
            if (!StringUtils.equals("0", price[0])) {
                FilterQuery filterQuery = new SimpleFilterQuery();
                Criteria filterCriteria = new Criteria("emp_salary").greaterThanEqual(price[0]);
                filterQuery.addCriteria(filterCriteria);
                query.addFilterQuery(filterQuery);
            }

            //薪资无穷大
            if (!StringUtils.equals("*", price[1])) {
                FilterQuery filterQuery = new SimpleFilterQuery();
                Criteria filterCriteria = new Criteria("emp_salary").lessThanEqual(price[1]);
                filterQuery.addCriteria(filterCriteria);
                query.addFilterQuery(filterQuery);
            }
        }

        // 1.6 分页
        Integer pageNum = (Integer) searchMap.get("pageNum");
        pageNum = pageNum != null ? pageNum : 1;
        Integer pageSize = (Integer) searchMap.get("pageSize");
        pageSize = pageSize != null ? pageSize : 20;

        //起始索引 分页公式(页码-1)*pageSize
        query.setOffset((pageNum - 1) * pageSize);
        //每页条数
        query.setRows(pageSize);


        //1.7 按照价格排序 ASC DESC
        String sortVal = (String) searchMap.get("sort");
        if (StringUtils.isNotBlank(sortVal)) {
            String sortField = (String) searchMap.get("sortField");
            Sort sort = new Sort(StringUtils.equals("ASC", sortVal) ? Sort.Direction.ASC : Sort.Direction.DESC, "emp_" + sortField);
            query.addSort(sort);
        }


        //********************* 获取高亮结果集 ***********************
        //返回 一个高亮页对象
        HighlightPage<Employee> page = solrTemplate.queryForHighlightPage(query, Employee.class);

        //高亮入口集合(每条记录的高亮入口)
        List<HighlightEntry<Employee>> entryList = page.getHighlighted();

        for (HighlightEntry<Employee> entry : entryList) {

            //获取高亮列表(高亮域的个数)
            List<HighlightEntry.Highlight> highlightList = entry.getHighlights();

            /*for (HighlightEntry.Highlight h : highlightList) {

                //由于每个域可能存储多值
                List<String> sms = h.getSnipplets();
            }*/

            if (highlightList != null && highlightList.size() > 0 && highlightList.get(0).getSnipplets().size() > 0) {
                Employee employee = entry.getEntity();
                employee.setUserName(highlightList.get(0).getSnipplets().get(0));
            }

        }

        //数据集
        map.put("rows", page.getContent());
        //总页数
        map.put("totalPages", page.getTotalPages());
        //总条数
        map.put("total", page.getTotalElements());
        return map;
    }

    //删除全部记录
    @Test
    public void delAll() {
        Query query = new SimpleQuery("*:*");
        solrTemplate.delete(query);
        solrTemplate.commit();
    }

    //根据主键删除
    @Test
    public void delById() {
        solrTemplate.deleteById("563528");
        solrTemplate.commit();
    }

    //分页查询
    @Test
    public void testPageQuery() {
        //查询对象
        SimpleQuery query = new SimpleQuery("*:*");
        //起始索引
        query.setOffset(10);
        //每页记录数
        query.setRows(50);

        //分页结果
        ScoredPage<Employee> page = solrTemplate.queryForPage(query, Employee.class);
        System.out.println("总记录数:" + page.getTotalElements());
        System.out.println("总页数:" + page.getTotalPages());
        for (Employee emp : page.getContent()) {
            System.out.println(emp);
        }
    }

    //条件查询
    @Test
    public void testConditionQuery() {
        //查询对象
        SimpleQuery query = new SimpleQuery("*:*");
        Criteria criteria = new Criteria("emp_userName").contains("刘一");

        query.addCriteria(criteria);
        ScoredPage<Employee> page = solrTemplate.queryForPage(query, Employee.class);
        System.out.println("匹配条数:" + page.getContent().size());
    }

    //根据 id 查询
    @Test
    public void findById() {
        Employee employee = solrTemplate.getById(4891920, Employee.class);
        System.out.println(employee);
    }

    //向Solr中 批量 新增数据
    @Test
    public void testAdd() {

        //模拟雇员名和头像
        String[] nameArr = {"刘一", "陈二", "张三", "李四", "王五", "赵六"};
        String[] avatarArr = {
                "http://39.105.173.146:8888/group1/M00/00/00/rBFs1l2IqpiAWwSRAACvSWwZ4Vk685.jpg",
                "http://39.105.173.146:8888/group1/M00/00/00/rBFs1l2IqpyAKBcEAABanhy4-9w450.jpg",
                "http://39.105.173.146:8888/group1/M00/00/00/rBFs1l2IqqGAYBtiAABxgy7RG9Q393.jpg",
                "http://39.105.173.146:8888/group1/M00/00/00/rBFs1l2IqqaAN6TWAABthLrydRU528.jpg"
        };

        //技能模拟
        String[] skillKey = new String[]{"Java", "Spring", "SpringMVC", "Mybatis", "Jenkins"};
        String[] skillVal = new String[]{"Java 是一门很好的语言", "Spring 是一个优秀的框架", "SpringMVC 是一个优秀的分层控制框架", "Mybatis 是一个很好的持久层框架", "Jenkins 是一个很好的持续化集成工具"};

        ArrayList<Employee> employeeArrayList = new ArrayList<>();

        for (int i = 0; i < 3000; i++) {
            // 用户名索引
            int index = (int) (Math.random() * 5);

            // 动态技能索引
            int keyIndex = (int) (Math.random() * 4);

            HashMap<String, String> strMap = new HashMap<>();
            strMap.put(skillKey[keyIndex], skillVal[keyIndex]);

            employeeArrayList.add(
                    new Employee()
                            .setId(((int) (Math.random() * 90000)) * ((int) (Math.random() * 900000)))
                            .setUserName(nameArr[index])
                            .setNickName(nameArr[index] + UUID.randomUUID().toString().substring(6).toUpperCase())
                            .setAvatar(avatarArr[(int) (Math.random() * 3)])
                            .setDescribe("您好,我叫:" + nameArr[index] + "、我的座右铭是:" + new String[]{"【你若精彩,天自安排。】", "【莫等闲、白了少年头、空悲切!!】", "【会当凌绝顶,一览众山小。】", "【懂得低头,才能出头。】"}[(int) (Math.random() * 3)])
                            .setOccupation(new String[]{"厨师", "高管", "项目经理", "架构师"}[(int) (Math.random() * 3)])
                            .setSalary((int) (Math.random() * 30000))
                            .setUpdTime(new Date())
                            .setSkillMap(strMap)
            );

        }

        //导入信息
        solrTemplate.saveBeans(employeeArrayList);
        solrTemplate.commit();
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值