boot整合solr

换了新项目组,技术相对老些,于是用boot框架简单记录下!

安装

下载路径:https://solr.apache.org/downloads.html

Windows环境

下载solr-8.2.0.zip包并解压缩,以管理员身份打开cmd,执行 solr cmd 命令启动solr

访问地址:ip:8983/

Linux环境

下载solr-8.2.0.tgz包 并执行以下命令

#1.解压缩

cd /opt
tar -xvf solr-8.2.0.tgz

#2.编辑sh脚本

cd ​solr-8.2.0/bin

vim solr.in.sh

补充内容:

​SOLR_ULIMIT_CHECKS=false

#3.启动

./solr start -force

 访问地址:ip:8983/

常用概念

核心(索引/表)

核心core:和数据库中的表一个意思,只是术语不同。可以看到页面上有个Core Admin,这个就是管理core的。

文档 doc

文档doc:相当于数据库中的一行数据。一个core由多条doc组成。

 结构 schema

结构schema:相当于数据库的表结构。常见结构schema:字段、字段类型、唯一键

分词

分词:就是将搜索内容拆分成一个个的词组。这个和以往数据库模糊匹配还不一样。

例如 在百度搜索时,搜索“我是好人”,会将搜索内容分成 我,是,好人。然后判断这几个分词在索引库中的出现次数,根据权重返回匹配信息。若用传统数据库mysql或oracle这种,直接会去用“我是好人”去模糊查询数据库,最后查询出的结果只能是 %我是好人% 这种数据。

但是搜索引擎会匹配出 %我%是%好人% 的数据。

倒排索引(反向索引)

说到倒排索引,提下正向索引。例如搜索“我是好人”,于是将分词 我,是,好人 分别去遍历每个文档,看是否有匹配数据。

倒排索引是 以分词为主键,文档ID为值的结构存储方式,其中文档ID升序存储,逗号分隔记录,节省了很大存储空间。当有搜索内容,只需分词后去匹配已倒排索引的数据得出最终的文档ID。

field标签常用属性

字段名称 name

字段类型 type

支持字段类型:

string 字符串
int, long 整数
float, double 浮点数
date 日期时间
bool 布尔类型
text 文本类型
binary 二进制类型

是否创建索引 indexed

indexed:当前字段是否创建索引,默认是true。创建索引后,可支持对该字段的搜索和过滤。

是否存储 sorted

sorted:当前字段是否存储到solr本身的存储库中,默认是true。此时不需要再次查询数据源显示数据。

是否启用点列存储 docValues

docValues:是否启用点列存储,默认是false。若需要做排序或者聚合查询处理都需要设置为true

是否多值 multiValues

multiValues:是否存储多个值,默认是false。若类型是数组,则需要设置为true。

安装ik中文分词器

版本与solr保持一致

下载地址:https://central.sonatype.com/artifact/com.github.magese/ik-analyzer

1.将ik-analyzer-8.2.0.jar包传输到/opt/solr-8.2.0/server/solr-webapp/webapp/WEB-INF/lib目录下

2.managed-schema文件补充  分词字段定义

<fieldType name="text_ik" class="solr.TextField"><analyzer type="index"><tokenizer class="org.wltea.analyzer.lucene.IKTokenizerFactory" useSmart="false" conf="ik.conf"/><filter class="solr.LowerCaseFilterFactory"/></analyzer><analyzer type="query"><tokenizer class="org.wltea.analyzer.lucene.IKTokenizerFactory" useSmart="false" conf="ik.conf"/><filter class="solr.LowerCaseFilterFactory"/></analyzer>
</fieldType>

将需要分词的字段类型调整为 text_ik

<field name="remarks" type="text_ik" indexed="true" stored="true" />

3.重启solr

./bin/solr stop -all
./bin/solr start -force

查看结果

修改分词器后,需要将索引删除后重新加载,solr重启后导入数据,方可根据分词器查询。

常用查询

通配符   

?匹配单个字符;

* 匹配任意个字符;

连接符   

&& 条件且;

|| 条件或;

查询   

value值用"",表示该值是精确查询;

例如remark:"备注" ;查询remark字段只为备注的文档

NOT查询 

value值用(* NOT "value1" NOT "value2"),表示不查询value值为value1和value2;

例如remark:(* NOT"送货") ;查询remark字段不为送货的文档

范围查询

value值用[v1 TO v2] 表示范围查询,[]表示包含,{}表示不包含;

例如id:[1 TO 2} 查询1<=id<2的文档

创建索引

在/opt/solr-8.2.0/server/solr目录下创建文件夹person

#1.创建文件夹

mkdir person

#2.将自带文件复制到该目录下

cp -R solr-8.2.0/server/solr/configsets/_default/conf/* solr-8.2.0/server/solr/person

修改managed-schema文件

<?xml version="1.0" encoding="UTF-8" ?><schema name="default-config" version="1.6"><!--  默认字段,不需要的可以删除  --><field name="id" type="long" indexed="true" stored="true" required="true" multiValued="false" /><field name="_version_" type="long" indexed="true" stored="true"/><field name="_text_" type="text_general" indexed="true" stored="false" multiValued="true"/><!--  定义字段 根据情况补充 --><field name="p_no" type="string" indexed="true" stored="true" required="true" multiValued="false" /><field name="p_name" type="string" indexed="true" stored="true" required="true" multiValued="false" /><field name="create_time" type="date" indexed="true" stored="true" required="true" multiValued="false" /><field name="create_user" type="string" indexed="true" stored="true" required="true" multiValued="false" /><field name="remarks" type="text_ik" indexed="true" stored="true" required="true" multiValued="false" /><field name="loves" type="string" indexed="true" stored="false" required="true" multiValued="true" /><uniqueKey>id</uniqueKey><!-- 要声明使用的type --><fieldType name="int" class="solr.TrieIntField" precisionStep="0" positionIncrementGap="0"/><fieldType name="string" class="solr.StrField" sortMissingLast="true" docValues="true" /><fieldType name="long" class="solr.TrieLongField" precisionStep="0" positionIncrementGap="0"/><fieldType name="double" class="solr.TrieDoubleField" precisionStep="0" positionIncrementGap="0"/><fieldType name="date" class="solr.TrieDateField" precisionStep="0" positionIncrementGap="0"/><!-- 保留 --><fieldType name="text_general" class="solr.TextField" positionIncrementGap="100" multiValued="true"><analyzer type="index"><tokenizer class="solr.StandardTokenizerFactory"/><filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" /><filter class="solr.LowerCaseFilterFactory"/></analyzer><analyzer type="query"><tokenizer class="solr.StandardTokenizerFactory"/><filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" /><filter class="solr.SynonymGraphFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/><filter class="solr.LowerCaseFilterFactory"/></analyzer></fieldType><!-- 中文分词器 --><fieldType name="text_ik" class="solr.TextField"><analyzer type="index"><tokenizer class="org.wltea.analyzer.lucene.IKTokenizerFactory" useSmart="false" conf="ik.conf"/><filter class="solr.LowerCaseFilterFactory"/></analyzer><analyzer type="query"><tokenizer class="org.wltea.analyzer.lucene.IKTokenizerFactory" useSmart="false" conf="ik.conf"/><filter class="solr.LowerCaseFilterFactory"/></analyzer></fieldType>
</schema>

修改solrconfig.xml文件

将所有调用及配置的add-schema-fields删除

solr设置账号密码

详情可见 前辈文章,下面也有记录

/opt/solr-8.2.0/server/etc目录

新建verify.properties文件,内容为 

# 用户名 密码 权限
solr: solr,admin

/opt/solr-8.2.0/server/contexts 目录

补充solr-jetty-context.xml文件,内容为

<!--添加配置权限认证:在文件configure中添加获取用户文件的配置,内容如下:--><Get name="securityHandler">    <Set name="loginService">    <New class="org.eclipse.jetty.security.HashLoginService">    <Set name="name">verify—name</Set> <Set name="config"><SystemProperty name="jetty.home" default="."/>/etc/verify.properties</Set>    </New>    </Set>    </Get>

/opt/solr-8.2.0/server/solr-webapp/webapp/WEB-INF目录

补充web.xml文件,内容为

<!--重新配置 security-resource-collection (删除之前的security-constraint,会导致登录的配置无效)--><security-constraint><web-resource-collection><web-resource-name>Solr</web-resource-name><url-pattern>/</url-pattern></web-resource-collection>   <auth-constraint>      <role-name>admin</role-name> </auth-constraint> </security-constraint><login-config>      <auth-method>BASIC</auth-method> <realm-name>verify-name</realm-name>   </login-config>

 重启solr,账号密码为solr/solr

boot整合

pom.xml文件补充依赖

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

application.yml文件补充配置

spring:data:solr:host: http://192.168.28.196:8983/solr # solr 服务地址username: solr #用户名password: solr #密码connectionTimeout: 10000 #连接超时socketTimeout: 3000 #读取超时

启动类开启solr配置

@EnableSolrRepositories(basePackages="com.example.demo.repository")

solr配置

package com.example.demo.config;import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.HttpRequestInterceptor;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.AuthState;
import org.apache.http.auth.Credentials;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.protocol.HttpContext;
import org.apache.http.protocol.HttpCoreContext;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.net.URI;/*** @Auther: lr* @Date: 2024/6/6 16:57* @Description:*/
@Configuration
public class SolrConfig {@Value("${spring.data.solr.username}")private String username;@Value("${spring.data.solr.password}")private String password;@Value("${spring.data.solr.host}")private String url;@Value("${spring.data.solr.connectionTimeout}")private Integer connectionTimeout;@Value("${spring.data.solr.socketTimeout}")private Integer socketTimeout;@Beanpublic HttpSolrClient solrClient(){//solr无账号密码
//        return new HttpSolrClient.Builder(url)
//                .withConnectionTimeout(connectionTimeout)
//                .withSocketTimeout(socketTimeout)
//                .build();//solr有账号密码 认证信息拦截CredentialsProvider provider = new BasicCredentialsProvider();final URI uri = URI.create(this.url);provider.setCredentials(new AuthScope(uri.getHost(), uri.getPort()),new UsernamePasswordCredentials(this.username, this.password));HttpClientBuilder builder = HttpClientBuilder.create();// 指定拦截器,用于设置认证信息builder.addInterceptorFirst(new SolrAuthInterceptor());builder.setDefaultCredentialsProvider(provider);CloseableHttpClient httpClient = builder.build();return new HttpSolrClient.Builder(this.url).withHttpClient(httpClient).withConnectionTimeout(connectionTimeout).withSocketTimeout(socketTimeout).build();}public static class SolrAuthInterceptor implements HttpRequestInterceptor {@Overridepublic void process(final HttpRequest request, final HttpContext context) {AuthState authState = (AuthState) context.getAttribute(HttpClientContext.TARGET_AUTH_STATE);if (authState.getAuthScheme() == null) {CredentialsProvider provider =(CredentialsProvider) context.getAttribute(HttpClientContext.CREDS_PROVIDER);HttpHost httpHost = (HttpHost) context.getAttribute(HttpCoreContext.HTTP_TARGET_HOST);AuthScope scope = new AuthScope(httpHost.getHostName(), httpHost.getPort());Credentials credentials = provider.getCredentials(scope);authState.update(new BasicScheme(), credentials);}}}}

实体类

package com.example.demo.entity;import lombok.Data;
import org.apache.solr.client.solrj.beans.Field;
import org.springframework.data.annotation.Id;
import org.springframework.data.solr.core.mapping.Indexed;
import org.springframework.data.solr.core.mapping.SolrDocument;import java.util.Date;
import java.util.List;/*** @Auther: lr* @Date: 2024/6/7 14:52* @Description:*/
@Data
@SolrDocument(collection = "person")
public class Person {@Id@Indexed(name = "id", type = "long")@Field("id")private Long id;@Indexed(name = "p_no", type = "string")@Field("p_no") //@Field 用于solr结果转实体类对象private String pNo;@Indexed(name = "p_name", type = "string")@Field("p_name")private String pName;@Indexed(name = "create_time", type = "date")@Field("create_time")private Date createTime;@Indexed(name = "create_user", type = "string")@Field("create_user")private String createUser;@Indexed(name = "remarks", type = "text_ik")@Field("remarks")private String remarks;@Indexed(name = "loves", type = "string")@Field("loves")private List<String> loves;
}

dao层

package com.example.demo.repository;import com.example.demo.entity.Person;
import org.springframework.data.solr.repository.SolrCrudRepository;
import org.springframework.stereotype.Repository;import java.util.List;/*** @Auther: lr* @Date: 2024/6/7 11:28* @Description:*/
@Repository
public interface PersonRepository extends SolrCrudRepository<Person, Long> {List<Person> findAll();List<Person> findByRemarks(String remarks);
}

controller类

package com.example.demo.controller;import com.example.demo.entity.Person;
import com.example.demo.repository.PersonRepository;
import org.apache.commons.lang3.StringUtils;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;import java.io.IOException;
import java.util.List;/*** @Auther: lr* @Date: 2024/6/7 9:42* @Description:*/
@RestController
@RequestMapping("/person")
public class SolrController {@AutowiredPersonRepository repository;@PostMapping("/addData")public void addData(@RequestBody Person person) throws Exception{repository.save(person);}@GetMapping("/queryAll")public List<Person> search() throws SolrServerException, IOException {List<Person> list  = repository.findAll();return list;}@GetMapping("/queryByRemarks")public List<Person> search(@RequestParam("remarks") String remarks) throws SolrServerException, IOException {List<Person> list  = repository.findByRemarks(remarks);return list;}@AutowiredHttpSolrClient solrClient;@GetMapping("queryByLoves")public List<Person> queryByLoves(@RequestParam("love") String love) throws IOException, SolrServerException {//设置查询条件SolrQuery query = new SolrQuery();if (!StringUtils.isEmpty(love)) {query.setQuery("loves:" + love);}if(StringUtils.isEmpty(query.getQuery())){query.setQuery("*:*");}query.setStart(0);query.setRows(5);QueryResponse response = solrClient.query("person",query);List<Person> list = response.getBeans(Person.class);return list;}
}

接口调用测试

在索引写文档信息

在索引查询文档信息

其他查询(聚合分组查询group)根据项目而定!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/24542.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

负反馈放大电路

开环放大倍数&#xff1a;放大电路没有加反馈时的放大倍数A 闭环放大倍数&#xff1a;电路加了反馈信号的放大倍数Af。反馈信号和输出信号的比值称为反馈系数F。 三极管各极电压变化关系 1&#xff0c;三极管的基极和发射极之间是同相关系&#xff0c;当基极电压上升&#x…

【Java】单例设计模式

单例设计模式简介 目录 1.单例设计模式是什么&#xff1f;2.单例设计模式设计方法饿汉式懒汉式 3.单例设计模式的应用任务管理器(仅有一个页面&#xff0c;不可多开)Runtime运行环境 1.单例设计模式是什么&#xff1f; 设计模式 是解决 特定问题的优秀设计方式之一。 单例设计…

怎么把m4a转换成mp3?四种常见的转换方法介绍!

怎么把m4a转换成mp3&#xff1f;在处理m4a音频文件时&#xff0c;我们可能会遇到一系列复杂的问题&#xff0c;首先&#xff0c;考虑到m4a是一种相对较新的音频格式&#xff0c;老旧的设备或软件可能无法准确识别它&#xff0c;这可能导致用户无法在这些设备上播放或编辑m4a文件…

西门子学习笔记10 - MCGS和西门子1200进行通讯设置

1、博图软件的设置 1、修改PLC的ip地址为192.168.1.1 2、打开put&#xff0c;get通讯功能 3、设置通讯变量&#xff0c;可以是M区也可以是DB块的数据 2、MCGSE组态环境设置 1、新建项目&#xff0c;在设备窗口界面进入设备窗口 2、添加设备如下 3、双击进入配置界面 4、添加变…

[线程与网络] 网络编程与通信原理(六):深入理解应用层http与https协议(网络编程与通信原理完结)

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏:&#x1f355; Collection与数据结构 (92平均质量分)https://blog.csdn.net/2301_80050796/category_12621348.html?spm1001.2014.3001.5482 &#x1f9c0;Java …

[职场] 美术学就业方向和前景 #经验分享#学习方法

美术学就业方向和前景 2011年国务院学位委员会、教育部颁布了新的《学位授予和人才培养学科目录》&#xff0c;艺术学首次从文学门类中独立出来&#xff0c;成为新的第13个学科门类&#xff0c;即艺术学门类。其中&#xff0c;美术学又是艺术学门类下的五个一级学科之一。但是…

亿发软件:信息化与数字化,相互交织的科技双引擎

在现代科技发展的浪潮中&#xff0c;信息化和数字化是两个频繁被提及的关键词。尽管它们在很多情况下被视为同义词&#xff0c;但其实两者有着本质的区别和相互影响的关系。究竟是信息化推动了数字化&#xff0c;还是数字化引领了信息化的进程&#xff1f;本文将深入探讨信息化…

数字驱动:企业发展的火箭助推器!

​ 在这个数字经济时代&#xff0c;数据就像火箭燃料&#xff0c;而数字驱动则是那强大的火箭助推器&#xff01;它正以惊人的力量助力企业飞速发展&#xff01; 数字驱动&#xff0c;助力企业发展的超强引擎&#xff01; 用数据说话&#xff0c;决策不再盲目&#xff01; 以数…

Vue CLI 环境变量使用指南

一、简介 Vue CLI 是一个强大的前端工程化工具&#xff0c;它提供了丰富的配置选项&#xff0c;包括环境变量的管理。环境变量允许开发者根据不同的运行环境&#xff08;如开发、测试和生产&#xff09;应用不同的配置&#xff0c;而无需更改代码。本文将详细介绍如何在 Vue C…

redis 03 RDB AOF

1.数据库状态 2.为什么会出现RDB 3.什么是RDB 5.1 5.2 6 6.1 6.2 6.2.1 6.2.2 6.2.3 7 8. 8.1 9 9.1 9.2 9.3 9.4 9.5

心链12-----队伍页业务完善+匹配算法实现随机匹配(最短距离算法)

心链 — 伙伴匹配系统 搜索队伍 我们选择vant组件库里的基础搜索框&#xff0c;复制到TeamPage页面&#xff0c;同时还有查询为空时&#xff0c;显示的无结果页面&#xff08;用户页面以写过&#xff09; 因为&#xff0c;我们一次性挂载本质性也是搜索队伍&#xff0c;所以…

@Validated 前端表单数据校验

1. 整合 1.1 依赖引入 <dependency><groupId>org.hibernate.validator</groupId><artifactId>hibernate-validator</artifactId></dependency>1.2 控制层 /*** 新增胎架计划** param subsectionPlanVo* return*/PostMapping("/sched…

数据结构复习指导之外部排序

目录 外部排序 复习提示 1.外部排序的基本概念 2.外部排序的方法 2.1对大文件排序时使用的排序算法&#xff08;2016&#xff09; 3.多路平衡归并与败者树 4.置换-选择排序&#xff08;生成初始归并段&#xff09; 4.1置换-选择排序生成初始归并段的实例(2023) 5.最佳…

【经验】Ubuntu上离线安装VsCode插件浏览Linux kernel源码

1、下载VsCode离线安装包 1.1 下载 下载地址:https://marketplace.visualstudio.com/vscode 本人安装的插件: C/C++ checkpatch Chinese clangd kconfig Makefile Tools Perl Perl Toolbox注意:C/C++插件要安装Linux 64版本 1.2 安装 将离线安装包拷贝到Ubuntu中,执…

SpringCloud整合OpenFeign实现微服务间的通信

1. 前言 1.1 为什么要使用OpenFeign&#xff1f; 虽说RestTemplate 对HTTP封装后, 已经⽐直接使⽤HTTPClient简单⽅便很多, 但是还存在⼀些问题. 需要拼接URL, 灵活性⾼, 但是封装臃肿, URL复杂时, 容易出错. 代码可读性差, ⻛格不统⼀。 1.2 介绍一下微服务之间的通信方式 微…

使用 stress 命令进行Linux CPU 压力测试

大家好&#xff0c;在现代计算机系统中&#xff0c;对系统性能和稳定性的评估是至关重要的。特别是在服务器环境中&#xff0c;我们需要确保系统能够在高负载情况下稳定运行&#xff0c;以满足用户的需求。而 CPU 是系统中最关键的组件之一&#xff0c;其性能直接影响着整个系统…

Python 快速查找并替换Excel中的数据

Excel中的查找替换是一个非常实用的功能&#xff0c;能够帮助用户快速完成大量数据的整理和处理工作&#xff0c;避免手动逐一修改数据的麻烦&#xff0c;提高工作效率。要使用Python实现这一功能&#xff0c; 我们可以借助Spire.XLS for Python 库&#xff0c;具体操作如下&am…

GAN网络理论和实验(二)

文章目录 一、说明二、什么是生成对抗网络&#xff1f;三、判别模型与生成模型四、生成对抗网络的架构五、你的第一个 GAN六、准备训练数据七、实现鉴别器八、实现生成器九、训练模型十、检查 GAN 生成的样本十一、使用 GAN 生成手写数字十二、准备训练数据十三、实现鉴别器和生…

笔记-2024视频会议软件技术选型方案

一、背景 视频会议系统是一种现代化的办公系统&#xff0c;它可以使不同会场的实时现场场景和语音互连起来&#xff0c;同时向与会者提供分享听觉和视觉的空间&#xff0c;使各与会方有“面对面”交谈的感觉。随着社会的发展&#xff0c;视频会议的应用越来越广泛&#xff0c;…

BC6 小飞机

BC6 小飞机 废话不多说先上题目&#xff1a; 代码如下&#xff1a; #include<stdio.h> int main() {printf(" ## \n############\n############\n # # \n # # \n");return 0; }这是用一个printf打印我们还可以用多个printf发打印代码如下…