侧边栏壁纸
博主头像
孔子说JAVA博主等级

成功只是一只沦落在鸡窝里的鹰,成功永远属于自信且有毅力的人!

  • 累计撰写 285 篇文章
  • 累计创建 125 个标签
  • 累计收到 4 条评论

目 录CONTENT

文章目录

SpringBoot整合solr集群

孔子说JAVA
2022-08-28 / 0 评论 / 0 点赞 / 53 阅读 / 16,006 字 / 正在检测是否收录...

solr服务器搭建起来后, 如果想要使数据加入到Solr服务器中,则在schema.xml中必须要存在与其对应的 Filed 标签声明,当我们添加一个对象时,可以一个一个的setFiled,当Filed较多的时候操作比较麻烦,Solr允许使用javaBean的方式将一个对象直接保存到solr服务器中。solrj 是 solr 的java客户端,用于访问solr索引库。它提供了添加、删除、查询、优化等功能。

image-1661506052847

1、定义 Schema 信息

假设我们需要操作一个描述诗人信息的文档,首先在schema.xml中定义Poet(诗人)对象的具体字段,字段说明如下:

字段 描述
id 唯一主键
age 年龄
name 姓名
poems 诗歌
about 简介
success 成就

定义的 schema 信息如下:

<field name="about" type="text_ik" uninvertible="true" indexed="true" stored="true"/>
<field name="age" type="pint" uninvertible="true" indexed="true" stored="true"/>
<field name="content" type="text_ik" uninvertible="true" indexed="true" stored="true" multiValued="true"/>
<field name="id" type="string" multiValued="false" indexed="true" required="true" stored="true"/>
<field name="name" type="text_ik" uninvertible="true" indexed="true" stored="true"/>
<field name="poems" type="text_ik" uninvertible="true" indexed="true" stored="true"/>
<field name="success" type="text_ik" uninvertible="true" indexed="true" stored="true"/>

2、springboot整合solr

Java 操作 SolrCloud 与操作 Solr 很类似,主要区别有:

  1. 连接使用的类不同,连接 Solr 使用的是 HttpSolrClient(springboot使用SolrClient),连接 SolrColud 使用的是 CloudHttp2SolrClient(springboot使用CloudSolrClient)。
  2. API 针对的操作对象不同,Solr 操作的是 core,SolrCloud 操作的是 collection。

2.1 引入依赖

solrj是solr的java客户端,用于访问solr索引库。它提供了添加、删除、查询、优化等功能。

springboot引入依赖方式1:

<properties>
    <spring.data.solr.version>2.1.1.RELEASE</spring.data.solr.version>
</properties>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-solr</artifactId>
            <version>${spring.data.solr.version}</version>
        </dependency>
    </dependencies>
</dependencyManagement>

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

    <!-- 默认 starter 会加载 solrj 进来, 下面这个可以不引-->
    <dependency>
        <groupId>org.apache.solr</groupId>
        <artifactId>solr-solrj</artifactId>
        <version>8.9.0</version>
    </dependency>
</dependencies>

springboot引入依赖方式2:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-solr</artifactId>
</dependency>

2.2 配置文件

server:
  context-path: /
  port: 8080
spring:
  data:
    solr:
      # 这里的node1、node2、node3就是solr集群节点名称
      zk-host: node1:2181,node2:2181,node3:2181

2.3 编写实体类

在java中建立实体对象,并且一定要在属性或set方法上添加@Field(nameValue)注解。(org.apache.solr.client.solrj.beans.Field)

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

public class PoetInfo {
    @Field
    private String id;

    @Field
    private Integer age;

    @Field
    private String name;

    @Field
    private String poems;

    @Field
    private String about;

    @Field
    private String success;

    public PoetInfo() {
    }

    public PoetInfo(String id, Integer age, String name, String poems, String about, String success) {
        this.id = id;
        this.age = age;
        this.name = name;
        this.poems = poems;
        this.about = about;
        this.success = success;
    }

    @Override
    public String toString() {
        return "Info{" +
                "id='" + id + '\'' +
                ", age=" + age +
                ", name='" + name + '\'' +
                ", poems='" + poems + '\'' +
                ", about='" + about + '\'' +
                ", success='" + success + '\'' +
                '}';
    }

    // getter、setter方法
}

2.4 solr的Config配置

CloudSolrClient的java配置类。

import org.apache.solr.client.solrj.impl.CloudSolrClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableMBeanExport;
import org.springframework.jmx.support.RegistrationPolicy;


@Configuration
@ComponentScan
@EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING)
public class SolrConfig {
    @Value("${solr.zk-host}")
    private String zkHost;

    @Bean
    public CloudSolrClient solrClient() {
        CloudSolrClient.Builder builder = new CloudSolrClient.Builder();
        builder.withZkHost(zkHost);
        CloudSolrClient solrClient = builder.build();
        return solrClient;
    }

}

2.5 solr基本操作类

import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.CloudSolrClient;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.params.MapSolrParams;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

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

/**
 * 使用solrJ 向solr 提交请求,增删改查, solrJ 底层页是发送 http 协议
 */
@Component
public class CloudSolrDAO {
    private static Logger logger = LoggerFactory.getLogger(CloudSolrDAO.class);

    @Autowired
    private CloudSolrClient solrClient;


    /**
     * 添加动态索引属性(增加/更新文档)
     *
     * @param collection 索引核心库
     * @throws SolrServerException
     * @throws IOException
     */
    public void addIndex(String collection) throws SolrServerException, IOException {
        SolrInputDocument document = new SolrInputDocument();
        // 默认情况下必须添加的字段,用来区分文档的唯一标识
        document.addField("id", "1");
        document.addField("age", 30);
        document.addField("name", "李白");
        document.addField("poems", "望庐山瀑布");
        document.addField("about", "字太白");
        document.addField("success", "创造了古代浪漫主义文学高峰、歌行体和七绝达到后人难及的高度");

        SolrInputDocument document2 = new SolrInputDocument();
        document2.addField("id", "2");
        document2.addField("age", 31);
        document2.addField("name", "杜甫");
        document2.addField("poems", "望岳");
        document2.addField("about", "字子美");
        document2.addField("success", "唐代伟大的现实主义文学作家,唐诗思想艺术的集大成者");
        /*
         * 如果spring.data.solr.host 里面配置到 core了, 这里就不需要传 coreName 这个参数了
         */
        solrClient.add(collection, document);
        solrClient.add(collection, document2);
        solrClient.commit(collection, true,true);
    }

    /**
     * 通过实体类来添加动态索引属性(增加/更新文档)
     *
     * @param collection 索引核心库
     * @throws SolrServerException
     * @throws IOException
     */
    public void addIndexByBean(String collection) throws SolrServerException, IOException {
        PoetInfo info = new PoetInfo("1", 40, "李白", "望庐山瀑布", "字太白", "创造了古代浪漫主义文学高峰、歌行体和七绝达到后人难及的高度");
        solrClient.addBean(collection, info);
        solrClient.commit(collection, true,true);
    }

    /**
     * 根据id删除索引
     *
     * @param collection 索引核心库
     * @param id
     * @throws SolrServerException
     * @throws IOException
     */
    public void delIndex(String collection, String id) throws SolrServerException, IOException {
        solrClient.deleteById(collection, id);
        solrClient.commit(collection, true,true);
    }

    /**
     * 根据名称删除索引
     *
     * @param collection 索引核心库
     * @param name 诗人姓名
     * @throws SolrServerException
     * @throws IOException
     */
    public void delIndexByName(String collection, String name) throws IOException, SolrServerException {
//        solrClient.deleteByQuery(collection, "name:杜甫");
        solrClient.deleteByQuery(collection, "name:"+name);
        solrClient.commit(collection, true,true);
    }

    /**
     * 通过 MapSolrParams 查询
     *
     * @param coreName 索引核心库
     * @throws IOException
     * @throws SolrServerException
     */
    public void query(String coreName) throws IOException, SolrServerException {
        Map<String, String> map = new HashMap<>();
        //查询条件
        map.put("q", "*:*");
        //要显示的内容
        map.put("fl", "id,age,name,poems");
        //排序方式
        map.put("sort", "id asc");
        MapSolrParams solrParams = new MapSolrParams(map);

        QueryResponse queryResponse = solrClient.query(coreName, solrParams);
        SolrDocumentList documents = queryResponse.getResults();
        logger.info("查询到{}个文档!", documents.getNumFound());
        for (SolrDocument document : documents) {
            String id = (String)document.getFieldValue("id");
            Integer age = (Integer)document.getFieldValue("age");
            String name = (String)document.getFieldValue("name");
            String poems = (String)document.getFieldValue("poems");
            logger.info("id={},age={},name={},poems={}", id, age, name, poems);
        }
    }

    /**
     * 通过 solrQuery 查询
     *
     * @param coreName 索引核心库
     * @throws IOException
     * @throws SolrServerException
     */
    public void solrQuery(String coreName) throws IOException, SolrServerException {
        SolrQuery solrQuery = new SolrQuery("*:*");
        solrQuery.addField("id");
        solrQuery.addField("age");
        solrQuery.addField("name");
        solrQuery.addField("poems");
        solrQuery.addSort("id", SolrQuery.ORDER.asc);
        //设置返回的行数
        solrQuery.setRows(10);

        QueryResponse queryResponse = solrClient.query(coreName, solrQuery);
        SolrDocumentList documents = queryResponse.getResults();
        logger.info("查询到{}个文档!", documents.getNumFound());
        for (SolrDocument document : documents) {
            String id = (String)document.getFieldValue("id");
            Integer age = (Integer)document.getFieldValue("age");
            String name = (String)document.getFieldValue("name");
            String poems = (String)document.getFieldValue("poems");
            logger.info("id={},age={},name={},poems={}", id, age, name, poems);
        }
    }

    /**
     * 查询返回实例类对象
     *
     * @param coreName 索引核心库
     * @throws IOException
     * @throws SolrServerException
     */
    public void solrQueryBean(String coreName) throws IOException, SolrServerException {
        SolrQuery solrQuery = new SolrQuery("*:*");
        solrQuery.addField("id");
        solrQuery.addField("age");
        solrQuery.addField("name");
        solrQuery.addField("poems");
        solrQuery.addField("about");
        solrQuery.addField("success");
        solrQuery.addSort("id", SolrQuery.ORDER.asc);
        //设置返回的行数
        solrQuery.setRows(10);

        QueryResponse queryResponse = solrClient.query(coreName, solrQuery);
        List<PoetInfo> list = queryResponse.getBeans(PoetInfo.class);
        logger.info("查询到{}个文档!", list.size());
        for (PoetInfo info : list) {
            logger.info(info.toString());
        }
    }
}

3、其他

CloudHttp2SolrClient的方式。

import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.CloudHttp2SolrClient;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.params.MapSolrParams;
import org.junit.After;
import org.junit.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 使用solrJ 向solr 提交请求,增删改查, solrJ 底层页是发送 http 协议
 */
@Component
public class CloudSolrDAO {
    private static Logger logger = LoggerFactory.getLogger(CloudSolrDAO.class);
    private CloudHttp2SolrClient solrClient;

    @Before
    public void before() {
        List<String> urls = new ArrayList<>();
        urls.add("http://10.40.96.135:8983/solr");
        urls.add("http://10.40.96.140:8983/solr");
        urls.add("http://10.40.96.144:8983/solr");
        solrClient = new CloudHttp2SolrClient.Builder(urls).build();
    }

    @After
    public void after() throws IOException {
        solrClient.close();
    }

    /**
     * 添加动态索引属性(增加/更新文档)
     *
     * @param collection 索引核心库
     * @throws SolrServerException
     * @throws IOException
     */
    public void addIndex(String collection) throws SolrServerException, IOException {
        SolrInputDocument document = new SolrInputDocument();
        // 默认情况下必须添加的字段,用来区分文档的唯一标识
        document.addField("id", "1");
        document.addField("age", 30);
        document.addField("name", "李白");
        document.addField("poems", "望庐山瀑布");
        document.addField("about", "字太白");
        document.addField("success", "创造了古代浪漫主义文学高峰、歌行体和七绝达到后人难及的高度");

        SolrInputDocument document2 = new SolrInputDocument();
        document2.addField("id", "2");
        document2.addField("age", 31);
        document2.addField("name", "杜甫");
        document2.addField("poems", "望岳");
        document2.addField("about", "字子美");
        document2.addField("success", "唐代伟大的现实主义文学作家,唐诗思想艺术的集大成者");
        /*
         * 如果spring.data.solr.host 里面配置到 core了, 这里就不需要传 coreName 这个参数了
         */
        solrClient.add(collection, document);
        solrClient.add(collection, document2);
        solrClient.commit(collection, true, true);
    }

    /**
     * 通过实体类来添加动态索引属性(增加/更新文档)
     *
     * @param collection 索引核心库
     * @throws SolrServerException
     * @throws IOException
     */
    public void addIndexByBean(String collection) throws SolrServerException, IOException {
        PoetInfo info = new PoetInfo("1", 40, "李白", "望庐山瀑布", "字太白", "创造了古代浪漫主义文学高峰、歌行体和七绝达到后人难及的高度");
        solrClient.addBean(collection, info);
        solrClient.commit(collection, true, true);
    }

    /**
     * 根据id删除索引
     *
     * @param collection 索引核心库
     * @param id
     * @throws SolrServerException
     * @throws IOException
     */
    public void delIndex(String collection, String id) throws SolrServerException, IOException {
        solrClient.deleteById(collection, id);
        solrClient.commit(collection, true, true);
    }

    /**
     * 根据名称删除索引
     *
     * @param collection 索引核心库
     * @param name       诗人姓名
     * @throws SolrServerException
     * @throws IOException
     */
    public void delIndexByName(String collection, String name) throws IOException, SolrServerException {
//        solrClient.deleteByQuery(collection, "name:杜甫");
        solrClient.deleteByQuery(collection, "name:" + name);
        solrClient.commit(collection, true, true);
    }

    /**
     * 通过 MapSolrParams 查询
     *
     * @param coreName 索引核心库
     * @throws IOException
     * @throws SolrServerException
     */
    public void query(String coreName) throws IOException, SolrServerException {
        Map<String, String> map = new HashMap<>();
        //查询条件
        map.put("q", "*:*");
        //要显示的内容
        map.put("fl", "id,age,name,poems");
        //排序方式
        map.put("sort", "id asc");
        MapSolrParams solrParams = new MapSolrParams(map);

        QueryResponse queryResponse = solrClient.query(coreName, solrParams);
        SolrDocumentList documents = queryResponse.getResults();
        logger.info("查询到{}个文档!", documents.getNumFound());
        for (SolrDocument document : documents) {
            String id = (String) document.getFieldValue("id");
            Integer age = (Integer) document.getFieldValue("age");
            String name = (String) document.getFieldValue("name");
            String poems = (String) document.getFieldValue("poems");
            logger.info("id={},age={},name={},poems={}", id, age, name, poems);
        }
    }

    /**
     * 通过 solrQuery 查询
     *
     * @param coreName 索引核心库
     * @throws IOException
     * @throws SolrServerException
     */
    public void solrQuery(String coreName) throws IOException, SolrServerException {
        SolrQuery solrQuery = new SolrQuery("*:*");
        solrQuery.addField("id");
        solrQuery.addField("age");
        solrQuery.addField("name");
        solrQuery.addField("poems");
        solrQuery.addSort("id", SolrQuery.ORDER.asc);
        //设置返回的行数
        solrQuery.setRows(10);

        QueryResponse queryResponse = solrClient.query(coreName, solrQuery);
        SolrDocumentList documents = queryResponse.getResults();
        logger.info("查询到{}个文档!", documents.getNumFound());
        for (SolrDocument document : documents) {
            String id = (String) document.getFieldValue("id");
            Integer age = (Integer) document.getFieldValue("age");
            String name = (String) document.getFieldValue("name");
            String poems = (String) document.getFieldValue("poems");
            logger.info("id={},age={},name={},poems={}", id, age, name, poems);
        }
    }

    /**
     * 查询返回实例类对象
     *
     * @param coreName 索引核心库
     * @throws IOException
     * @throws SolrServerException
     */
    public void solrQueryBean(String coreName) throws IOException, SolrServerException {
        SolrQuery solrQuery = new SolrQuery("*:*");
        solrQuery.addField("id");
        solrQuery.addField("age");
        solrQuery.addField("name");
        solrQuery.addField("poems");
        solrQuery.addField("about");
        solrQuery.addField("success");
        solrQuery.addSort("id", SolrQuery.ORDER.asc);
        //设置返回的行数
        solrQuery.setRows(10);

        QueryResponse queryResponse = solrClient.query(coreName, solrQuery);
        List<PoetInfo> list = queryResponse.getBeans(PoetInfo.class);
        logger.info("查询到{}个文档!", list.size());
        for (PoetInfo info : list) {
            logger.info(info.toString());
        }
    }
}
0

评论区