Solr7.x学习-使用spring-data-solr

Posted 一个笨蛋的博客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Solr7.x学习-使用spring-data-solr相关的知识,希望对你有一定的参考价值。

1、maven配置

<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-solr</artifactId>
    <version>4.0.10.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.apache.solr</groupId>
    <artifactId>solr-solrj</artifactId>
    <version>7.7.2</version>
</dependency>

2、application-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
                https://www.springframework.org/schema/beans/spring-beans.xsd
                http://www.springframework.org/schema/data/solr
                https://www.springframework.org/schema/data/solr/spring-solr.xsd">

    <solr:solr-client id="solrClient" url="${solr.url}" />
    <solr:repositories base-package="com.zhi.demo.**.repository" />

    <bean name="solrTemplate" class="org.springframework.data.solr.core.SolrTemplate">
        <constructor-arg name="solrClient" ref="solrClient" />
        <!-- 根据Indexed注解创建不存在的字段 -->
        <property name="schemaCreationFeatures">
            <list>
                <value>CREATE_MISSING_FIELDS</value>
            </list>
        </property>
    </bean>
</beans>

注意schemaCreationFeatures选择,如果有CREATE_MISSING_FIELDS选择,Spring会在启动时根据Indexed注解在solr中创建没定义的field。关键代码:

 

 

 3、创建Bean

    Dept.java

package com.zhi.demo.dept.model;

import java.util.Date;

import org.springframework.data.annotation.Id;
import org.springframework.data.solr.core.mapping.Indexed;
import org.springframework.data.solr.core.mapping.SolrDocument;

/**
 * 部门信息,collection为对应的core名称,Indexed注解会自动在solr添加对应的field
 * 
 * @author zhi
 * @time 2016年12月22日09:55:08
 *
 */
@SolrDocument(collection = "dept")
public class Dept {
    /**
     * 部门ID
     */
    @Id
    @Indexed
    private String id;
    /**
     * 部门名称
     */
    @Indexed(type = "text_ik")
    private String name;
    /**
     * 创建时间
     */
    @Indexed(name = "createTime", type = "pdate")
    private Date createTime;
    /**
     * 备注
     */
    @Indexed(type = "text_ik")
    private String remark;

    public Dept() {
        super();
    }

    public Dept(String id, String name, Date createTime, String remark) {
        super();
        this.id = id;
        this.name = name;
        this.createTime = createTime;
        this.remark = remark;
    }

    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 Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public String getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }

}
View Code

    Person.java

package com.zhi.demo.person.model;

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

import org.springframework.data.annotation.Id;
import org.springframework.data.solr.core.mapping.Indexed;

/**
 * 人员信息
 * 
 * @author 张远志
 * @time 2016年12月22日09:55:42
 *
 */
@SuppressWarnings("serial")
public class Person implements Serializable {
    /**
     * 主键
     */
    @Id
    @Indexed
    private String id;
    /**
     * 人员名称
     */
    @Indexed
    private String name;
    /**
     * 地址
     */
    @Indexed
    private String addr;
    /**
     * 年龄
     */
    private Integer age;
    /**
     * 部门ID
     */
    private String deptId;
    /**
     * 是否可用
     */
    private boolean usable;
    /**
     * 创建时间
     */
    private Date createTime;
    /**
     * 备注
     */
    private String remark;

    public Person() {
        super();
    }

    public Person(String id, String name, String addr, Integer age, String deptId, boolean usable, Date createTime,
            String remark) {
        super();
        this.id = id;
        this.name = name;
        this.addr = addr;
        this.age = age;
        this.deptId = deptId;
        this.usable = usable;
        this.createTime = createTime;
        this.remark = remark;
    }

    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 getAddr() {
        return addr;
    }

    public void setAddr(String addr) {
        this.addr = addr;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getDeptId() {
        return deptId;
    }

    public void setDeptId(String deptId) {
        this.deptId = deptId;
    }

    public boolean isUsable() {
        return usable;
    }

    public void setUsable(boolean usable) {
        this.usable = usable;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public String getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }

}
View Code

4、使用Repository方式进行CRUD操作

    创建DeptRepository.java

package com.zhi.demo.dept.repository;

import java.util.List;

import org.springframework.data.solr.repository.Query;
import org.springframework.data.solr.repository.SolrCrudRepository;

import com.zhi.demo.dept.model.Dept;

/**
 * 部门增删改查操作
 * 
 * @author zhi
 * @since 2019年9月27日14:05:15
 *
 */
public interface DeptRepository extends SolrCrudRepository<Dept, String> {

    @Query("name:?0 OR remark:?0")
    List<Dept> findList(String text);
}
View Code

    定义Dept操作接口和实现

package com.zhi.demo.dept.service;

import java.util.List;

import com.zhi.demo.dept.model.Dept;

/**
 * 部门操作接口
 * 
 * @author zhi
 * @since 2019年9月27日13:12:26
 *
 */
public interface IDeptService {
    /**
     * 保存
     * 
     * @param model
     * @return
     */
    Dept save(Dept model);

    /**
     * 批量保存
     * 
     * @param models
     * @return
     */
    List<Dept> saveBatch(List<Dept> models);

    Dept findById(String id);

    List<Dept> list(String text);
}
View Code
package com.zhi.demo.dept.service.impl;

import java.util.List;
import java.util.Optional;

import org.apache.commons.collections4.IteratorUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.zhi.demo.dept.model.Dept;
import com.zhi.demo.dept.repository.DeptRepository;
import com.zhi.demo.dept.service.IDeptService;

/**
 * 部门操作接口实现
 * 
 * @author zhi
 * @since 2019年9月27日13:12:26
 *
 */
@Service
public class DeptServiceImpl implements IDeptService {
    @Autowired
    private DeptRepository deptRepository;

    @Override
    public Dept save(Dept model) {
        deptRepository.save(model);
        return model;
    }

    @Override
    public List<Dept> saveBatch(List<Dept> models) {
        deptRepository.saveAll(models);
        return models;
    }

    @Override
    public Dept findById(String id) {
        Optional<Dept> optional = deptRepository.findById(id);
        if (optional.isPresent()) {
            return optional.get();
        }
        return null;
    }

    @Override
    public List<Dept> list(String text) {
        if (StringUtils.isEmpty(text)) {
            return IteratorUtils.toList(deptRepository.findAll().iterator());
        } else {
            return deptRepository.findList(text);
        }
    }
}
View Code

     Junit测试

package com.zhi.test;

import java.util.List;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.zhi.demo.dept.model.Dept;
import com.zhi.demo.dept.service.IDeptService;

/**
 * Solr部门测试
 * 
 * @author zhi
 * @since 2019年9月29日15:06:06
 *
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:application.xml", "classpath*:application-*.xml" })
public class DeptTest {
    private Logger logger = LogManager.getLogger(this.getClass());
    @Autowired
    private IDeptService deptService;

    @Test
    public void saveBatch() {
        try {
            deptService.saveBatch(ModelData.getDeptData());
            logger.info("保存成功");
        } catch (Exception e) {
            logger.error("保存出错", e);
        }
    }

    @Test
    public void findOne() {
        try {
            Dept dept = deptService.findById("01");
            if (dept == null) {
                logger.info("根据ID未查询到记录");
            } else {
                logger.info("查询结果:id={},name={},remark{}", dept.getId(), dept.getName(), dept.getRemark());
            }
        } catch (Exception e) {
            logger.error("查询出错", e);
        }
    }

    @Test
    public void list() {
        try {
            List<Dept> list = deptService.list("公司");
            logger.info("查询到的数据长度:{}", list.size());
            for (Dept dept : list) {
                logger.info("id={},name={},remark{}", dept.getId(), dept.getName(), dept.getRemark());
            }
        } catch (Exception e) {
            logger.error("查询出错", e);
        }
    }
}
View Code

5、使用SolrTemplate进行CRUD删除

    定义接口和实现

package com.zhi.demo.person.service;

import java.util.List;

import com.zhi.demo.person.model.Person;

/**
 * 人员操作接口
 * 
 * @author zhi
 * @since 2019年9月27日11:33:31
 *
 */
public interface IPersonService {
    /**
     * 保存人员,
     * 
     * @param model
     * @return
     */
    Person save(Person model);

    /**
     * 批量保存人员
     * 
     * @param models
     * @return
     */
    List<Person> saveBatch(List<Person> models);

    /**
     * 根据ID查询人员信息
     * 
     * @param id
     * @return
     */
    Person findById(String id);

    /**
     * 根据关键字查询人员列表
     * 
     * @param text 与name和addr字段匹配
     * @return 列表长度由solr默认分页长度决定
     */
    List<Person> list(String text);

    /**
     * 根据可用状态查找人员列表
     * 
     * @param usable 与usable字段匹配
     * @return 列表长度由solr默认分页长度决定
     */
    List<Person> usable(Boolean usable);
}
View Code
package com.zhi.demo.person.service.impl;

import java.time.Duration;
import java.util.List;
import java.util.Optional;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.solr.core.SolrTemplate;
import org.springframework.data.solr.core.query.Criteria;
import org.springframework.data.solr.core.query.SimpleQuery;
import org.springframework.data.solr.core.query.SimpleStringCriteria;
import org.springframework.stereotype.Service;

import com.zhi.demo.person.model.Person;
import com.zhi.demo.person.service.IPersonService;

/**
 * 人员操作接口实现
 * 
 * @author zhi
 * @since 2019年9月27日11:33:31
 *
 */
@Service
public class PersonServiceImpl implements IPersonService {
    @Autowired
    private SolrTemplate solrTemplate;

    @Override
    public Person save(Person model) {
        solrTemplate.saveBean("person", model);
        solrTemplate.commit("person"); // 手工提交数据
        return model;
    }

    @Override
    public List<Person> saveBatch(List<Person> models) {
        solrTemplate.saveBeans("person", models, Duration.ofSeconds(2)); // 自动提交
        return models;
    }

    public Person findById(String id) {
        Criteria criteria = new Criteria("id");
        criteria.is(id);
        Optional<Person> optional = solrTemplate.queryForObject("person", new SimpleQuery(criteria), Person.class);
        return optional.isPresent() ? optional.get() : null;
    }

    @Override
    public List<Person> list(String text) {
        SimpleQuery query = new SimpleQuery();
        if (!StringUtils.isEmpty(text)) {
            Criteria criteria = new SimpleStringCriteria("name:" + text + " OR addr:" + text);
            query.addCriteria(criteria);
        }
        Page<Person> page = solrTemplate.query("person", query, Person.class);
        return page.getContent();
    }

    @Override
    public List<Person> usable(Boolean usable) {
        SimpleQuery query = new SimpleQuery();
        if (usable != null) {
            Criteria criteria = new Criteria("usable");
            criteria.is(usable);
            query.addCriteria(criteria);
        }
        Page<Person> page = solrTemplate.query("person", query, Person.class);
        return page.getContent();
    }
}
View Code

    Junit测试

package com.zhi.test;

import java.util.Date;
import java.util.List;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.zhi.demo.person.model.Person;
import com.zhi.demo.person.service.IPersonService;
import com.zhi.demo.utils.TimerUtil;

/**
 * Solr人员操作测试
 * 
 * @author 张远志
 * @since 2019年9月29日15:34:55
 *
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:application.xml", "classpath*:application-*.xml" })
public class PersonTest {
    private Logger logger = LogManager.getLogger(this.getClass());
    @Autowired
    private IPersonService personService;

    @Test
    public void saveBatch() {
        try {
            personService.saveBatch(ModelData.getPersonData());
            logger.info("保存成功");
        } catch (Exception e) {
            logger.error("保存出错", e);
        }
    }

    @Test
    public void findOne() {
        try {
            Person model = personService.findById("01");
            if (model == null) {
                logger.info("根据ID未查询到记录");
            } else {
                logger.info("查询结果:id={},name={},addr={}", model.getId(), model.getName(), model.getAddr());
            }
        } catch (Exception e) {
            logger.error("查询出错", e);
        }
    }

    @Test
    public void list() {
        try {
            List<Person> list = personService.list("武汉");
            logger.info("查询到的数据长度:{}", list.size());
            for (Person item : list) {
                logger.info("id={},name={},addr={}", item.getId(), item.getName(), item.getAddr());
            }
        } catch (Exception e) {
            logger.error("查询出错", e);
        }
    }

    @Test
    public void usable() {
        try {
            List<Person> list = personService.usable(false);
            logger.info("查询到的数据长度:{}", list.size());
            for (Person item : list) {
                logger.info("id={},name={},addr={}", item.getId(), item.getName(), item.getAddr());
            }
        } catch (Exception e) {
            logger.error("查询出错", e);
        }
    }

    @Test
    public void pressure() {
        Date start = new Date();
        for (int i = 0; i < 10000; i++) {
            personService.list("武汉");
        }
        logger.info(TimerUtil.format(start));
    }
}
View Code

 

以上是关于Solr7.x学习-使用spring-data-solr的主要内容,如果未能解决你的问题,请参考以下文章

spring-data-es 基本操作使用

Solr7.x安装部署教程

Spring Boot整合Solr7.x

Solr 7.x 是不是支持 Java 11?

ELK3.spring boot 2.X集成ES spring-data-ES 进行CRUD操作 完整版

solr 7.x 配置ikanalyzer