SpringBoot集成Solr全文检索

SrpingBoot 集成 Solr 实现全文检索

一、核心路线

  1. 使用 Docker 镜像部署 Solr 8.11.3 版本服务
  2. 使用 ik 分词器用于处理中文分词
  3. 使用 spring-boot-starter-data-solr 实现增删改查
  4. 配置用户名密码认证
  5. 使用 poi 和 pdfbox 组件进行文本内容读取
  6. 文章最上方有源码和 ik 分词器资源

二、Solr Docker 镜像制作

由于 Solr 官方镜像无法通过环境变量直接配置用户名密码认证,所以选用第三方的 bitnami/solr 镜像作为基础,将 ik 分词器插件封装后得到新的镜像。

  1. 拉取 bitnami/solr 镜像

    docker pull bitnami/solr:8.11.3
    
  2. 下载 ik 分词器 jar 包 ik-analyzer-8.5.0.jar

  3. 编写 Dockerfile 文件

    FROM  bitnami/solr:8.11.3COPY  ./ik-analyzer-8.5.0.jar  /opt/bitnami/solr/server/solr-webapp/webapp/WEB-INF/lib/CMD  ["/opt/bitnami/scripts/solr/run.sh"]
    
  4. 构建镜像

    docker build -t bitnami/solr:8.11.3-ik .
    

三、部署 Solr 服务

方式一:普通 docker 命令行部署
  1. 创建数据目录,例如 /home/solr-data

  2. 启动容器

    docker run -d -p 8983:8983 --name solr \-v /home/solr-data:/bitnami \-e SOLR_ENABLE_AUTHENTICATION=yes \-e SOLR_CORES=my_core \-e SOLR_ADMIN_USERNAME=admin \-e SOLR_ADMIN_PASSWORD=SolrPass \bitnami/solr:8.11.3-ik
    
方式二:Rancher 云平台部署

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

由于 solr 镜像默认使用 solr 用户启动容器,挂载的 pvc 没有写入权限,需要按照以下步骤进行:

  1. 以 UID=0 即 root 用户进行启动,并且入口 Entrypoint 使用 /bin/bash 覆盖默认启动命令,然后进入容器命令行

  2. 修改数据目录属主

    chown -R solr:solr /bitnami/
    
  3. 去掉入口(Entrypoint)命令,用户 UID 设置为 1000 即 solr,重启工作负载即可

四、配置 Solr 用户权限

  1. 访问 http://localhost:8983 即可打开 solr 控制台,输入账号密码 admin/SolrPass 登录认证

  2. 为了演示方便,直接给 admin 用户赋予全部权限

    在这里插入图片描述

    在这里插入图片描述

五、配置 my_core 的 ik 分词

编辑 /bitnami/solr/server/solr/my_core/conf/managed-schema 配置文件,追加以下配置内容:

  <!--ik 分词插件配置--><fieldType name="text_ik" class="solr.TextField"><analyzer type="index"><tokenizer class="org.wltea.analyzer.lucene.IKTokenizerFactory" conf="ik.conf" useSmart="false"/><filter class="solr.LowerCaseFilterFactory"/></analyzer><analyzer type="query"><tokenizer class="org.wltea.analyzer.lucene.IKTokenizerFactory" conf="ik.conf" useSmart="true"/><filter class="solr.LowerCaseFilterFactory"/></analyzer></fieldType>

配置完成后重启 solr 容器。

六、创建 SpringBoot 工程

pom.xml 文件
<?xml version="1.0" encoding="UTF-8"?>
<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>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.4.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.example</groupId><artifactId>solr-example</artifactId><version>1.0-SNAPSHOT</version><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--Solr--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-solr</artifactId></dependency><!--Solr 认证--><dependency><groupId>commons-codec</groupId><artifactId>commons-codec</artifactId></dependency><!--读取 docx 文档内容--><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>5.2.2</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>5.2.2</version></dependency><!--读取 doc 文档内容--><dependency><groupId>org.apache.poi</groupId><artifactId>poi-scratchpad</artifactId><version>5.2.2</version></dependency><!--读取 PDF 文档内容--><dependency><groupId>org.apache.pdfbox</groupId><artifactId>pdfbox</artifactId><version>2.0.26</version></dependency><!--Hutool 工具类--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.2</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency></dependencies><build><finalName>${project.artifactId}</finalName><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>2.3.3.RELEASE</version><executions><execution><phase>package</phase><goals><goal>repackage</goal><!--可以把依赖的包都打包到生成的Jar包中--></goals></execution></executions></plugin></plugins></build></project>
配置文件
server:port: 18888
spring:servlet:# 文件上传配置multipart:enabled: truemax-file-size: 100MBmax-request-size: 100MBdata:solr:host: http://localhost:8983/solr # solr 服务地址username: admin # solr 用户名password: SolrPass # solr 密码
工程启动类
package com.example.solr;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.solr.repository.config.EnableSolrRepositories;@EnableSolrRepositories // 启用 solr repository
@SpringBootApplication
public class SolrExampleApplication {public static void main(String[] args) {SpringApplication.run(SolrExampleApplication.class, args);}
}
SolrConfig 配置类

该类用于配置 Solr 认证

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;@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 uri;/****  配置 solr 账号密码*/@Beanpublic HttpSolrClient solrClient() {CredentialsProvider provider = new BasicCredentialsProvider();final URI uri = URI.create(this.uri);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.uri).withHttpClient(httpClient).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);}}}
}
MyDocument 实体类
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
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.io.Serializable;@Data
@NoArgsConstructor
@AllArgsConstructor
@SolrDocument(collection = "my_core") // 此处配置 core 信息
public class MyDocument implements Serializable {@Id@Fieldprivate String id;// 使用 string 类型即不进行分词@Indexed(name = "type", type = "string")private String type;// 使用 text_ik 类型即使用 ik 分词器进行分词索引和查询@Indexed(name = "title", type = "text_ik")private String title;// 使用 text_ik 类型即使用 ik 分词器进行分词索引和查询@Indexed(name = "content", type = "text_ik")private String content;
}
MyDocumentRepository 类

该类用于和 solr 服务进行通信,实现增删改查操作。

import com.example.solr.entity.MyDocument;
import org.springframework.data.domain.Pageable;
import org.springframework.data.solr.core.query.result.HighlightPage;
import org.springframework.data.solr.repository.Highlight;
import org.springframework.data.solr.repository.Query;
import org.springframework.data.solr.repository.SolrCrudRepository;import java.util.List;public interface MyDocumentRepository extends SolrCrudRepository<MyDocument, String> {/*** 按类型进行查询** @param type 类型* @return 查询结果*/@Query("type:?0")List<MyDocument> findAllByType(String type);/*** 按照标题或内容进行模糊查询,并且对关键词进行高亮标记* snipplets = 3 用于指定查询出符合条件的结果数,不指定则只能查出一条** @param title    标题关键词* @param content  内容关键词* @param pageable 分页对象* @return 带有高亮标记的查询结果*/@Highlight(snipplets = 3, fields = {"title", "content"}, prefix = "<span style='color:red'>", postfix = "</span>")HighlightPage<MyDocument> findAllByTitleOrContent(String title, String content, Pageable pageable);
}
MyDocumentService 类
import com.example.solr.entity.MyDocument;
import org.springframework.data.domain.Pageable;import java.util.List;
import java.util.Map;public interface MyDocumentService {MyDocument save(MyDocument document);void saveAll(List<MyDocument> documentList);void delete(String id);MyDocument findById(String id);List<MyDocument> findAllByType(String type);List<Map<String, Object>> findAllByTitleOrContent(String searchItem, Pageable pageable);
}

对应的实现类

import com.example.solr.entity.MyDocument;
import com.example.solr.repository.MyDocumentRepository;
import com.example.solr.service.MyDocumentService;
import org.springframework.data.domain.Pageable;
import org.springframework.data.solr.core.query.result.HighlightEntry;
import org.springframework.data.solr.core.query.result.HighlightPage;
import org.springframework.stereotype.Service;import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;@Service
public class MyDocumentServiceImpl implements MyDocumentService {@Resourceprivate MyDocumentRepository repository;@Overridepublic MyDocument save(MyDocument document) {return repository.save(document);}@Overridepublic void saveAll(List<MyDocument> documentList) {repository.saveAll(documentList);}@Overridepublic void delete(String id) {repository.delete(findById(id));}@Overridepublic MyDocument findById(String id) {return repository.findById(id).orElse(null);}@Overridepublic List<MyDocument> findAllByType(String type) {return repository.findAllByType(type);}@Overridepublic List<Map<String, Object>> findAllByTitleOrContent(String searchItem, Pageable pageable) {// 查询分页结果HighlightPage<MyDocument> page = repository.findAllByTitleOrContent(searchItem, searchItem, pageable);List<Map<String, Object>> result = new ArrayList<>();// 处理查询结果高亮片段for (HighlightEntry<MyDocument> highlight : page.getHighlighted()) {// 每个 map 对应一个文档Map<String, Object> map = new HashMap<>();MyDocument doc = highlight.getEntity();map.put("id", doc.getId());map.put("type", doc.getType());map.put("title", doc.getTitle());for (HighlightEntry.Highlight hl : highlight.getHighlights()) {map.put(hl.getField().getName(), hl.getSnipplets());}result.add(map);}return result;}
}
FileUtil 文件内容处理类
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.extractor.WordExtractor;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.springframework.web.multipart.MultipartFile;import java.io.IOException;
import java.io.InputStream;@Slf4j
public class FileUtil {/*** 读取文档内容* 目前仅支持 txt, doc, docx, pdf 格式** @param file 文件对象* @return 文档内容*/public static String readFileContent(MultipartFile file) {String filename = file.getOriginalFilename();assert filename != null;String fileType = filename.substring(filename.lastIndexOf(".") + 1).toUpperCase();switch (fileType) {case "TXT":return readTxtContent(file);case "DOC":case "DOCX":return readWordContent(file);case "PDF":return readPDFContent(file);default:return "";}}/*** 读取 txt 文档内容*/private static String readTxtContent(MultipartFile file) {try {return StrUtil.utf8Str(file.getBytes());} catch (IOException e) {e.printStackTrace();log.error("读取 txt 文件内容时发生 IO 异常");return "";}}/*** 读取 doc 和 docx 文档内容*/private static String readWordContent(MultipartFile file) {String filename = file.getOriginalFilename();assert filename != null;String fileType = filename.substring(filename.lastIndexOf(".") + 1);return "doc".equals(fileType) ? readDocContent(file) : readDocxContent(file);}/*** 读取 .doc 格式的 word 文档** @param file 文件对象* @return 文本内容*/private static String readDocContent(MultipartFile file) {StringBuilder content = new StringBuilder();try (InputStream inputStream = file.getInputStream();HWPFDocument document = new HWPFDocument(inputStream)) {WordExtractor extractor = new WordExtractor(document);String[] paragraphs = extractor.getParagraphText();for (String paragraph : paragraphs) {content.append(paragraph);}} catch (IOException e) {e.printStackTrace();log.error("读取文件内容时发生 IO 异常");}return content.toString();}/*** 读取 .docx 格式的 word 文档** @param file 文件对象* @return 文本内容*/private static String readDocxContent(MultipartFile file) {StringBuilder content = new StringBuilder();try (InputStream inputStream = file.getInputStream();XWPFDocument document = new XWPFDocument(inputStream)) {for (XWPFParagraph paragraph : document.getParagraphs()) {for (XWPFRun run : paragraph.getRuns()) {String runText = run.getText(0);if (runText != null) {content.append(runText);}}}} catch (IOException e) {e.printStackTrace();log.error("读取文件内容时发生 IO 异常");}return content.toString();}/*** 读取 pdf 文档内容*/private static String readPDFContent(MultipartFile file) {StringBuilder content = new StringBuilder();try (InputStream inputStream = file.getInputStream();PDDocument document = PDDocument.load(inputStream)) {// 检查是否是由文档转换出的 pdf 文件if (!document.isEncrypted() && document.getNumberOfPages() > 0) {PDFTextStripper textStripper = new PDFTextStripper();content.append(textStripper.getText(document));} else {log.warn("PDF 已加密或不是由文档转换的 PDF 格式,无法读取内容!");}} catch (IOException e) {e.printStackTrace();log.error("读取文件内容时发生 IO 异常");}return content.toString();}
}
MyDocumentController 控制器类
package com.example.solr.controller;import com.example.solr.entity.MyDocument;
import com.example.solr.service.MyDocumentService;
import com.example.solr.util.FileUtil;
import org.springframework.data.domain.PageRequest;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;@RestController
@RequestMapping("/solr")
public class MyDocumentController {@Resourceprivate MyDocumentService documentService;/*** 上传文档文件,读取文档内容并写入 solr** @param file 上传的文档文件,仅支持读取以下格式的文件内容 txt, doc, docx, pdf(由文档转换生成的)* @param type 文件分类* @return 处理结果*/@PostMapping("/upload")public Map<String, Object> upload(@RequestPart("multipartFile") MultipartFile file, @RequestParam String type) {MyDocument doc = new MyDocument();doc.setId(UUID.randomUUID().toString());doc.setType(type);doc.setTitle(file.getOriginalFilename());doc.setContent(FileUtil.readFileContent(file));documentService.save(doc);Map<String, Object> result = new HashMap<>();result.put("result", true);result.put("data", doc);return result;}/*** 直接向 solr 添加内容** @param type    类型* @param title   标题* @param content 内容* @return 处理结果*/@PostMapping("/save")public Map<String, Object> save(@RequestParam String type, @RequestParam String title, @RequestParam String content) {MyDocument doc = new MyDocument();doc.setId(UUID.randomUUID().toString());doc.setType(type);doc.setTitle(title);doc.setContent(content);documentService.save(doc);Map<String, Object> result = new HashMap<>();result.put("result", true);result.put("data", doc);return result;}/*** 删除 solr 内容** @param id 主键* @return 处理结果*/@DeleteMapping("/delete")public Map<String, Object> delete(@RequestParam String id) {documentService.delete(id);Map<String, Object> result = new HashMap<>();result.put("result", true);result.put("data", null);return result;}/*** 根据标题或内容模糊搜索,并且高亮关键词** @param searchItem 搜索关键词* @param page       页码* @param size       每页数量* @return 查询结果*/@GetMapping("/searchTitleOrContent")public Map<String, Object> searchTitleOrContent(@RequestParam String searchItem, @RequestParam Integer page,@RequestParam Integer size) {List<Map<String, Object>> data = documentService.findAllByTitleOrContent(searchItem, PageRequest.of(page, size));Map<String, Object> result = new HashMap<>();result.put("result", true);result.put("data", data);return result;}/*** 根据类型搜索** @param type 类型* @return 查询结果*/@GetMapping("/searchType")public Map<String, Object> searchType(@RequestParam String type) {List<MyDocument> data = documentService.findAllByType(type);Map<String, Object> result = new HashMap<>();result.put("result", true);result.put("data", data);return result;}
}

七、验证

启动服务,使用 postman 等工具进行接口请求。

1. 直接写入 solr 内容

在这里插入图片描述

2. 上传 word 文档读取内容写入 solr

在这里插入图片描述

3. 根据类型精确查询

在这里插入图片描述

4. 根据标题或内容模糊查询

在这里插入图片描述

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

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

相关文章

【晴问算法】入门篇—字符串处理—单词数

题目描述 给定一堆用空格隔开的英文单词&#xff0c;统计单词个数。输入描述 一堆英文单词&#xff0c;每个单词不超过10个字符&#xff0c;且仅由大小写字母组成;每两个单词之间用一个空格隔开&#xff0c;整个字符串的长度不超过1000。输出描述 输出一个整数&#xff0c;表示…

视频汇聚平台EasyCVR启用图形验证码之后调用login接口的操作方法

视频综合管理平台EasyCVR视频监控系统支持多协议接入、兼容多类型设备&#xff0c;平台可以将区域内所有部署的监控设备进行统一接入与集中汇聚管理&#xff0c;实现对监控区域的实时高清视频监控、录像与存储、设备管理、云台控制、语音对讲、级联共享等&#xff0c;在监控中心…

【网络爬虫】(2) requests模块,案例:网络图片爬取,附Python代码

1. 基本原理 1.1 requests 模块 requests 是 Python 中一个非常流行的 HTTP 客户端库&#xff0c;用于发送所有的 HTTP 请求类型。它基于 urllib&#xff0c;但比 urllib 更易用。 中文文档地址&#xff1a;Requests: 让 HTTP 服务人类 — Requests 2.18.1 文档 &#xff0…

OpenHarmony 源码解析之SystemUi—Statusbar(TS)

作者&#xff1a;董伟 简介 SystemUI应用是OpenHarmony中预置的系统应用&#xff0c;为用户提供系统相关信息展示及交互界面&#xff0c;包括系统状态、系统提示、系统提醒等&#xff0c;例如系统时间、电量信息。 本文主要分析batterycomponent、clockcomponent、wificompo…

[Windows常用软件] word 复制粘贴报错修复

背景 在word 内 ctrlv 会报这个错。 microsoft visual basic MathPage.Wll 运行时错误 网上查了一下是 mathtype 导致的&#xff0c;应该是我之前卸载 mathtype 没有卸载干净导致的。 解决方案 参考知乎里面的一个回答解决的&#xff1a;https://www.zhihu.com/question/37…

高防服务器、高防IP、高防CDN的工作原理是什么

高防IP高防CDN我们先科普一下是什么是高防。“高防”&#xff0c;顾名思义&#xff0c;就犹如网络上加了类似像盾牌一样很高的防御&#xff0c;主要是指IDC领域的IDC机房或者线路有防御DDOS能力。 高防服务器主要是比普通服务器多了防御服务&#xff0c;一般都是在机房出口架设…

网络七层模型之网络层:理解网络通信的架构(三)

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

centos 7安装pgsql14

参考 yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm终端直接运行&#xff1a;yum install -y postgresql14-server 1. 初始化数据库 使用yum安装后&#xff0c;会在系统中创建一个postgres的无密码…

【快速解决】谷歌浏览器驱动的安装及selenium的安装

目录 快速安装Selenium 快速下载对应谷歌驱动 找不到对应版本号的解决方法 快速安装Selenium 安装 Selenium 环境就用下面的代码进行安装&#x1f447;&#x1f447;&#x1f447;&#x1f447;&#x1f447; pip install selenium3.141.0 快速下载对应谷歌驱动 点击这个链接…

关于RPC

初识RPC RPC VS REST HTTP Dubbo Dubbo 特性&#xff1a; 基于接口动态代理的远程方法调用 Dubbo对开发者屏蔽了底层的调用细节&#xff0c;在实际代码中调用远程服务就像调用一个本地接口类一样方便。这个功能和Fegin很类似&#xff0c;但是Dubbo用起来比Fegin还要简单很多&a…

pe启动盘破解windows密码wins电脑登录密码修改重置

目录 1.进入电脑BIOS&#xff0c;设置电脑第一启动项为U盘启动2.进入微pe系统3.然后点击界面最左下方的Windows图标4.点击windows密码选择对应用户名称修改&#xff1b; 1.进入电脑BIOS&#xff0c;设置电脑第一启动项为U盘启动 把u盘插到要清除密码的电脑&#xff0c;然后开机…

Java语法学习 正则表达式

Java语法学习 正则表达式 大纲 具体案例 需求&#xff1a;使用正则表达式完成对文本的查询&#xff0c;regular expression&#xff08;正则表达式&#xff09; 源码解析group package com.wantian.regular;import java.util.regex.Matcher; import java.util.regex.Patt…

日新增百万数据clickhouse大数据解决方案记录分享

公司广告业务需求&#xff0c;需要多个维度统计每个应用的设备数&#xff0c;点击率&#xff0c;展示率&#xff0c;等相关数据&#xff0c;而且数据需要进行去重&#xff0c;我第一时间想到的是利用clickhouse来做统计&#xff0c;因为我们平台访问量比较大&#xff0c;用mysq…

浅谈WPF之MVVM工具包

在之前的WPF示例中&#xff0c;都会用到一个MVVM框&#xff0c;也是一个比较常的MVVM框架&#xff0c;就是MVVM工具包【CommunityToolkit.Mvvm】&#xff0c;今天专门以一个简单的小例子&#xff0c;简述一下MVVM工具包的常见用法&#xff0c;仅供学习分享使用&#xff0c;如有…

选项式API和组合式API的区别

选项式(options) API 和组合式(composition) API两种不同的风格书写&#xff0c;Vue3 的组件可以使用这两种api来编写。 选项式API和组合式API的区别 选项式API 选项式 API&#xff0c;具有相同功能的放在一起&#xff0c;可以用包含多个选项的对象来描述组件的逻辑&…

WPF---1.入门学习

学习来源 布局 wpf布局原则 一个窗口中只能包含一个元素 不应显示设置元素尺寸 不应使用坐标设置元素的位置 可以嵌套布局容器 StackPanel-->表单条件查找布局 DataGrid wpf布局容器 StackPanel: 水平或垂直排列元素&#xff0c;Orientation属性分别: Horizontal / Vertic…

Java数据结构-ArrayList

目录 1. 初识集合框架2. ArrayList的介绍3. ArrayList的使用3.1 构造方法3.2 add3.3 addAll3.4 remove3.5 get3.6 set3.7 contains3.8 IndexOf3.9 lastIndexOf3.10 subList 4. ArrayList的遍历4.1 简单粗暴法4.2 循环遍历法4.3 迭代器 1. 初识集合框架 Java集合框架是Java编程…

基于OneAPI+ChatGLM3-6B+FastGPT搭建LLM大语言模型知识库问答系统

搭建大语言模型知识库问答系统 部署OneAPI部署一个LLM模型部署嵌入模型部署FastGPT新建FastGPT对话应用新建 FastGPT 知识库应用 部署OneAPI 拉取镜像 docker pull justsong/one-api创建挂载目录 mkdir -p /usr/local/docker/oneapi启动容器 docker run --name one-api -d …

粘包/半包及解决方案

一、粘包/半包介绍 1&#xff1a;粘包 粘包&#xff08;Packet Concatenation&#xff09;通常发生在基于流式传输协议&#xff08;如 TCP&#xff09;的通信中&#xff0c;因为 TCP 是面向流的传输协议&#xff0c;它不保证数据包的边界&#xff0c;而是将数据视为连续的字节…

密码学及其应用1 —— 密码学概述

1 密码学的基本概念 1.1 网络安全的定义 网络安全是网络领域的一个专业领域&#xff0c;它涵盖了在基础计算机网络基础设施中所采取的措施、网络管理员为保护网络及网络可访问资源免受未授权访问而采纳的政策&#xff0c;以及对其有效性&#xff08;或无效性&#xff09;的持续…