当前位置: 首页 > news >正文

【微服务】RedisSearch 使用详解

目录

一、RedisJson介绍

1.1 RedisJson是什么

1.2 RedisJson特点

1.3 RedisJson使用场景

1.3.1 数据结构化存储

1.3.2 实时数据分析

1.3.3 事件存储和分析

1.3.4 文档存储和检索

二、当前使用中的问题

2.1 刚性数据库模式限制了敏捷性

2.2 基于磁盘的文档存储导致瓶颈

2.3 附加索引和全文搜索增加了复杂性

2.4 小规模数据量下的准实时搜索问题

三、RedisSearch介绍

3.1 什么是RedisSearch

3.2 RedisSearch功能特性

3.3 与mongodb和es对比

四、RedisSearch安装

4.1 启动镜像

4.2 检查测试

五、RedisJson/ RedisSearch命令使用

5.1 RedisJson操作命令

5.1.1 保存操作

5.1.2 读取操作

5.1.3 批量读取操作

5.1.4 删除操作

5.2 RedisSearch操作命令

5.2.1 创建索引

5.2.2 为索引添加内容

5.2.3 根据关键字查询

5.3 RedisSearch 扩展使用

5.3.1 前置准备

5.3.2 查询全部数据

5.3.3 查询并按照字段排序

5.3.4 返回指定字段

5.3.5 模糊查询

5.3.6 查询范围区间的数据

5.3.7 关键词检索

5.3.8 高亮显示

5.3.9 删除索引

六、Java操作RedisJson

6.1 引入基本依赖

6.2 相关操作API

七、SpringBoot操作RedisJson

7.1 添加配置文件

7.2 添加jedis配置类

7.3 测试类

八、写在文末


一、RedisJson介绍

1.1 RedisJson是什么

RedisJSON是一个Redis模块,它实现了JSON数据交换标准ECMA-404,作为原生数据类型。它允许从Redis中存储、更新和获取JSON值;

  • RedisJSON 是一种高性能 JSON 文档存储,允许开发人员构建现代应用程序。它在内存中存储和处理 JSON,以亚毫秒级支持每秒数百万次操作响应时间;
  • JSON 文档的原生索引、查询和全文搜索允许开发人员创建二级索引,快速查询数据;

1.2 RedisJson特点

redisJson具有如下特点:

  • 完全支持JSON标准;
  • 使用类似JSONPath的语法,用于在文档中选择元素;
  • 文档以二进制数据的形式存储在树结构中,允许快速访问子元素;
  • 所有JSON值类型都是原子操作

1.3 RedisJson使用场景

在下面的这些场景下可以考虑使用RedisJson

1.3.1 数据结构化存储

redisJson允许将复杂的JSON数据存储在redis中,并可以使用Redis的查询功能来快速检索和操作这些数据。


1.3.2 实时数据分析

通过将结构化数据存储在RedisJson中,可以轻松的对数据进行实时分析和计算。


1.3.3 事件存储和分析

RedisJson可以用作事件驱动的存储系统。用于存储和分析事件流数据。


1.3.4 文档存储和检索

RedisJson提供了一些内置的查询功能,可以轻松的在存储的JSON数据中执行文档检索。

二、当前使用中的问题

通过上面的内容我们了解了RedisJson的基本内容,并了解了使用RedisJson可以解决的问题和应用场景,Redis常用的数据结构已经很强大了,可以说已经能够满足大多数的业务场景了,为什么还要了解和学习RedisJson这个点呢?在弄清这个问题之前,先来看看现有的一些业务场景下存在的问题。

2.1 刚性数据库模式限制了敏捷性

传统的关系型数据库,一旦数据库表结构随着业务确定下来,中途想要针对某个表扩展新字段将是一件非常麻烦的事,甚至可能会对团队现有的工作节奏造成难以预估的冲击。简单来说就是,传统的数据库模式限制了业务机动调整的灵活性和自由性。

2.2 基于磁盘的文档存储导致瓶颈

文档类型的结构数据,允许开发人员使用灵活的 JSON 数据模型更快地迭代。 然而,由于磁盘 I/O性能瓶颈, 导致应用程序写入缓慢和读取延迟高。

2.3 附加索引和全文搜索增加了复杂性

我们知道在mysql5.7之后的版本,要实现全文检索功能,可以考虑使用全文索引,但使用过mysql全文索引的同学大多数会得出一个结论就是,不好用,用起来限制较多,不够灵活,但在mysql如果不用全文索引实现,使用其他方式将会增加更大的难度和复杂度。

2.4 小规模数据量下的准实时搜索问题

试想你的系统数据规模并不是很大,只是系统中的某些业务场景需要使用实时搜索,或者存在高性能检索的需求,在这种场景下,引入其他高性能数据存储成本会大大增加,同时这也将给开发和运维带来新的工作量。

综上论述,在下面的场景中可能需要使用RedisJson改进或优化你的使用:

  • 数据规模较小的场景下需要完成实时检索,使用mysql无法满足高性能检索场景;
  • 数据结构类json文档,且存在文档结构的扩展;
  • 能够实现全文检索;
  • 存储简单,运维成本低,系统接入成本低;
  • ...

三、RedisSearch介绍

在上文中我们了解了为什么需要使用RedisJson,其实总结一句话就是,需要基于RedisJson使用其全文检索功能,同时还能方便的对存储其中的JSON文档或字段进行增删改查。

3.1 什么是RedisSearch

RediSearch 是一个高性能的全文搜索引擎,它可以作为一个 Redis Module(扩展模块)运行在 Redis 服务器上,在2.x之后的版本它不在使用基于RDB的基础数据结构,而是采用了一种全新的文件存储结构对数据进行索引,而且性能上也有了成倍的提升。

3.2 RedisSearch功能特性

RedisSearch主要特性如下:

  • 多字段联合检索;
  • 高性能增量索引;
  • 复杂布尔查询;
  • 基于管道的查询子句;
  • 基于前缀的搜索;
  • 支持字段权重设置;
  • 自动完成建议(可用于搜索框联想词提示);
  • 精确的短语搜索;
  • 在许多语言中基于词干分析的查询扩展;
  • 支持自定义评分函数(类似ES的function_score);
  • 将搜索限制到特定的文档字段;
  • 数字过滤器和范围;
  • 使用 Redis 自己的地理命令进行地理过滤;
  • 检索完整的文档内容或只是 ID 的检索;
  • 支持文档删除和更新与索引垃圾收集;
  • 支持部分更新和条件文档更新;
  • 支持拼写纠错;
  • 支持高亮显示;
  • 支持聚合分析;
  • 支持配置停用词和同义词;
  • 支持向量存储与KNN检索(重磅);
  • ...

3.3 与mongodb和es对比

结合已有的使用经验对比:

  • RedisSearch 2.2 (支持RedisJson *) 比以前的版本更快;
  • RedisJson * 在直接读取、写入和更新工作负载方面比Mongodb和es更快;
  • 在混合工作负载场景中,实时更新不会影响RedisJson *的搜索和读取性能,而es则会受到影响;

尽管来说从测试的数据来看,在一定情况下RedisSearch的性能确实比es或mongo要高很多,但是两者的使用场景还是有区别的,这点需要额外关注。

四、RedisSearch安装

官方安装手册地址:Install Redis Stack | Redis ,官方提供了多种安装部署方式,这里选择使用Docker来搭建一个RedisSearch的环境。参考下面的安装流程。

4.1 启动镜像

使用下面的命令启动RedisSearch

docker run -p 6379:6379 -d --name=myredis redislabs/redisearch:latest

4.2 检查测试

安装完成之后使用 redis-cli 来检查 RediSearch 模块是否加载成功,使用 Docker 启动 redis-cli,命令如下:

docker exec -it myredis redis-cli

在基础命令的使用上,RedisSearch与之前并没有什么区分,可以理解是原生的redis的一种升级版。使用下面的命令检查下安装的RediSearch 包括的功能模块

module list

看到下面的效果,说明RedisSearch模块加载成功

五、RedisJson/ RedisSearch命令使用

接下来对RedisSearch与RedisJson中的常用操作命令通过案例做一下深入的使用和了解。

5.1 RedisJson操作命令

5.1.1 保存操作

语法

JSON.SET <key> <path> <json>  [NX | XX]

参数说明:

  • 对于新的Key,path需要使用$或 .;
  • 对于已经存在Key,在进行保存操作之后,原来path路径的值将会被替换掉;
  • NX:表示只有Key不存在,才执行保存操作;
  • XX:表示只有Key存在,才执行保存操作;
  • 通过命令type doc可以查看到存储进去的数据是ReJSON-RL类型;

使用下面的命令添加一条json数据

JSON.SET json_1 . '{"name":"jerry","age":22,"city":"hangzhou"}'

5.1.2 读取操作

语法

JSON.GET <key>[INDENT indentation-string][NEWLINE line-break-string][SPACE space-string][path ...]

参数说明:

  • 允许使用多个path进行查询;
  • INDENT 查询结果替换掉默认缩进字符(用于返回Pretty-formatted JSON);
  • NEWLINE 查询结果替换掉默认换行符(用于返回Pretty-formatted JSON);
  • SPACE 查询结果替换掉默认空格(用于返回Pretty-formatted JSON);
  • 获取JSON对象中的属性时需要以.开头

使用下面的命令获取上面添加进去的数据

JSON.GET json_1

5.1.3 批量读取操作

语法

JSON.MGET <key> [key ...] <path>

参数说明:

  • 最后一个参数作为path进行处理;
  • 遍历每一个Key的path,如果不存在,则返回null;

准备两条数据

JSON.SET json_1 . '{"name":"jerry","age":22,"city":"hangzhou"}'

JSON.SET json_2 . '{"name":"mike","age":26,"city":"beijing"}'

使用mget批量获取多条数据

5.1.4 删除操作

语法

JSON.DEL <key> [path]

参数说明

  • path是可选的,如果没有输入,则默认整个Key删除掉;

更多redisJson命令参考文档说明:Commands | Redis

5.2 RedisSearch操作命令

RedisSearch的操作可以说是与RedisJson密不可分的,两者在使用上具有一定的前后关系,简单理解就是RedisSearch通常操作的数据就是RedisJson结构的数据。

5.2.1 创建索引

RedisSearch在使用之前,需要提前定义json数据结构的相关属性,包括指定索引命名,json中的字段类型等,这就有点像操作mysql表需要提前创建表一样。

ft.create myidx schema title text weight 5.0 desc text

参数说明:

  • “myidx”为索引的ID;
  • 此索引包含了两个字段“title”和“desc”;
  • “weight”为权重,默认值为 1.0;

5.2.2 为索引添加内容

添加内容到上面的索引

ft.add myidx doc1 1.0 fields title "He urged her to study English" desc "good idea"

其中“doc1”为文档 ID(docid),“1.0”为评分(score)

5.2.3 根据关键字查询

使用下面的语句查询索引中包含 english关键字的数据

ft.search myidx "english" limit 0 10

5.3 RedisSearch 扩展使用

上面演示了一下使用RedisJson和RedisSearch的基本操作命令,下面继续深入研究一下RedisSearch更深入的使用。

5.3.1 前置准备

定义json模板

FT.CREATE itemIdx ON JSON LANGUAGE chinese SCHEMA $.name AS name TEXT $.description as description TEXT $.brandName AS brandName TAG $.price AS price NUMERIC SORTABLE

参数说明:

  • FT.CREATE itemIdx :创建一个名为 itemIdx 的 RedisSearch索引;
  • 此命令创建一个索引,该索引代表 与JSON 文档中的name、description 、brandName和price相关联进行索引,设置索引语言为chinese:

SCHEMA 这部分定义了索引的字段和他们的数据类型

  • $.name as name TEXT : 定义了一个名为name的文本字段,对应于JSON键 $name ,这个字段存储的是文本类型的数据;
  • $.description as description TEXT : 定义了一个名为description 的文本字段,对应于JSON键 $description ,这个字段存储的是文本类型的数据;
  • $.brandName as brandName TAG : 定义了一个名为brandName 的TAG字段,对应于JSON键 $brandName ,这个字段存储的是TAG类型的数据;
  • $.price as price NUMERIC : 定义了一个名为price的文本字段,对应于JSON键 $price ,这个字段存储的是NUMERIC类型的数据;

支持的常用的数据类型

  • TEXT(文本):用于存储文本类型的数据,可以进行全文搜索和模糊匹配;
  • NUMERIC(数值):用于存储数值数据,支持范围查询和聚合操作;
  • TAG(标签):用于存储标签或分类信息,支持过滤和聚合操作;
  • VECTOR(向量):用于存储多维向量数据,支持基于向量相似性的搜索;

执行下面的语句为上述自定义json索引添加几条数据

JSON.SET a1 $ '{"name": "Iphone 15plus","description": "Iphone15-16G-25G","brandName":"Iphone","price": 5699}'JSON.SET a2 $ '{"name": "华为Mate60 pro","description": "HuaWei-32G-512G","brandName":"华为","price": 7799}'

5.3.2 查询全部数据

建立完索引后,我们就可以使用FT.SEARCH对数据进行查看了,比如使用*可以查询全部;

5.3.3 查询并按照字段排序

设置了price字段为SORTABLE,我们可以以price降序返回查询数据

5.3.4 返回指定字段

FT.SEARCH itemIdx * RETURN 2 name price

5.3.5 模糊查询

还可以使用像like一样的模糊查询,例:查询name以华为开头的

FT.SEARCH item '@name:华为*'

5.3.6 查询范围区间的数据

使用如下语句查询价格在5000~6000的商品; 

FT.SEARCH itemIdx '@price:[5000 6000]'

5.3.7 关键词检索

FT.SEARCH中直接指定搜索关键词,可以对所有TEXT类型的属性进行全局搜索,支持中文搜索

FT.SEARCH itemIdx 'Iphone'

5.3.8 高亮显示

使用HIGHLIGHT来进行高亮显示效果(默认对搜索关键字加上<b></b>),HIGHLIGHT必须跟在return后面,return 1 name表示返回一个name字段;对name字段高亮显示。测试了一下,高亮只对TEXT类型有效

FT.SEARCH itemIdx '@name:(华为)' return 1 name HIGHLIGHT

5.3.9 删除索引

使用FT.DROPINDEX命令可以删除索引,如果不加DD只会删除索引,与索引关联的JSON文档不会删除;如果加入DD选项的话,会连数据一起删除;

FT.DROPINDEX itemIdx DD

小结:

细心的同学可能会发现,在Redis的基本数据结构中,Hash这种数据结构和json很类似,因为它们两者存储的都是json类型结构的数据,但是使用JSON的方式与HASH相比,JSON更快。在对数据做修改时,hash需要删除整个文档再将修改后的文档添加,而json可以直接对文档中的某一字段修改。

六、Java操作RedisJson

在Java中操作RedisJson和RedisSearch毕比较简单的方式就是使用jedis,下面演示如何基于jedis来操作RedisJson和RedisSearch

6.1 引入基本依赖

这里注意引入的jedis的版本,我这里使用的是4.0以上的版本,版本太低的话某些与RedisJson相关的API可能无法使用

        <!--测试单元 --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency><!--用来操作redis --><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>4.0.1</version></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.15</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>${lomok.version}</version></dependency>

6.2 相关操作API

下面给出了使用RedisJson的方式操作对象的相关API,以及RedisSearch的操作API

import cn.hutool.core.lang.Console;
import cn.hutool.json.JSONUtil;
import com.congge.entity.TbUser;
import org.junit.Test;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.UnifiedJedis;
import redis.clients.jedis.providers.PooledConnectionProvider;
import redis.clients.jedis.search.*;import java.util.List;public class RedisJsonTest {static UnifiedJedis client;static {// redis连接HostAndPort config = new HostAndPort("IP", 6379);PooledConnectionProvider provider = new PooledConnectionProvider(config);client = new UnifiedJedis(provider);}/*** 添加json数据*/public static void addJson(){TbUser tbUser1 = new TbUser("jerry",30,"杭州西湖区");TbUser tbUser2 = new TbUser("mike",29,"北京东城区");TbUser tbUser3 = new TbUser("john",28,"武汉汉口");// 添加jsonclient.jsonSet("user:1", redis.clients.jedis.json.Path.ROOT_PATH,tbUser1);client.jsonSet("user:2",redis.clients.jedis.json.Path.ROOT_PATH,tbUser2);client.jsonSet("user:3",redis.clients.jedis.json.Path.ROOT_PATH,tbUser3);System.out.println("添加json数据成功");}/*** 根据key查询对象数据*/public static void getFromJsonKey(){// 查询TbUser student = client.jsonGet("user:1", TbUser.class,redis.clients.jedis.json.Path.ROOT_PATH);System.out.println(JSONUtil.toJsonStr(student));}/*** 创建索引*/public static void createIndex(){Schema schema = new Schema().addField(new Schema.Field(new FieldName("$.userName", "userName"), Schema.FieldType.TEXT)).addField(new Schema.Field(new FieldName("$.address", "address"), Schema.FieldType.TEXT));// 只索引key以user:开头的IndexDefinition rule = new IndexDefinition(IndexDefinition.Type.JSON).setPrefixes("user:");// 创建索引client.ftCreate("user-index",IndexOptions.defaultOptions().setDefinition(rule),schema);System.out.println("索引创建成功");}/*** 根据索引中的字段查询*/public static void queryByIndexField(){// 查询名字以John开头的学生,并高亮显示Query q = new Query("@userName:jerry")//.highlightFields(new Query.HighlightTags("<b>","</b>"),"userName").returnFields("userName","address");SearchResult searchResult = client.ftSearch("user-index", q);List<Document> documents = searchResult.getDocuments();for(Document document : documents){Console.log(JSONUtil.toJsonStr(document));System.out.println();document.getProperties().forEach(item ->{System.out.println(item.getKey());System.out.println(item.getValue());});}}public static void main(String[] args) {//addJson();//getFromJsonKey();//createIndex();queryByIndexField();}}

下面是根据某个字段的查询结果

七、SpringBoot操作RedisJson

基于上述使用jedis操作RedisJson与RedisSearch的操作,接下来演示如何与springboot进行整合

7.1 添加配置文件

添加application.yaml配置文件,主要配置redis相关的信息,参考如下内容

server:port: 8087spring:jackson:date-format: yyyy-MM-dd HH:mm:sstime-zone: GMT+8redis:database: 0host: IPport: 6379jedis:pool:max-active: 30

7.2 添加jedis配置类

该配置类即为全局注入一个jedis的客户端,可以在需要调用的位置直接注入使用

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.UnifiedJedis;
import redis.clients.jedis.providers.PooledConnectionProvider;@Configuration
public class UnifiedJedisClientConfig {@Value("${spring.redis.host}")private String host;@Value("${spring.redis.port:6379}")private Integer port;@Beanpublic UnifiedJedis unifiedJedis() {HostAndPort config = new HostAndPort(host, 6379);PooledConnectionProvider provider = new PooledConnectionProvider(config);UnifiedJedis unifiedJedis = new UnifiedJedis(provider);return unifiedJedis;}}

7.3 测试类

编写一个测试接口

@RestController
public class UserRedisJsonController {private static final Logger logger = LoggerFactory.getLogger(UserRedisJsonController.class);@Autowiredprivate UnifiedJedis jedis;//localhost:8087/addJson@GetMapping("/addJson")public String add(){TbUser tbUser1 = new TbUser("jerry",30,"杭州西湖区");TbUser tbUser2 = new TbUser("mike",29,"北京东城区");TbUser tbUser3 = new TbUser("john",28,"武汉汉口");// 添加jsonjedis.jsonSet("user:1", redis.clients.jedis.json.Path.ROOT_PATH,tbUser1);jedis.jsonSet("user:2",redis.clients.jedis.json.Path.ROOT_PATH,tbUser2);jedis.jsonSet("user:3",redis.clients.jedis.json.Path.ROOT_PATH,tbUser3);System.out.println("添加json数据成功");return "success";}/*** 根据key查询对象数据* localhost:8087/getFromJsonKey*/@GetMapping("/getFromJsonKey")public  void getFromJsonKey(){// 查询TbUser tbUser = jedis.jsonGet("user:1", TbUser.class,redis.clients.jedis.json.Path.ROOT_PATH);System.out.println(JSONUtil.toJsonStr(tbUser));}@GetMapping("/createIndex")public String createIndex(){// 创建索引createIndex("users-index","users:", new String[]{"userName","address"});return "索引创建成功";}public boolean createIndex(String indexName, String key, String... fields){try {try{Map<String, Object> map = jedis.ftInfo(indexName);logger.info("index configuration:{}",map);jedis.ftDropIndex(indexName);} catch (Exception e){logger.error("the index does not exist", e);}Schema schema = new Schema();float weight = 1.0f;for(String field : fields) {String attribute;if (!StringUtils.isEmpty(field)) {if (field.indexOf(".") == -1) {attribute = field;} else {String[] fieldSplit = field.split("\\.");attribute = fieldSplit[fieldSplit.length - 1];}if (attribute.toLowerCase().startsWith("geo")) {Schema.Field field1 = new Schema.Field(FieldName.of("user:" + field).as(attribute), Schema.FieldType.GEO);schema.addField(field1);continue;} else {Schema.TextField textField = new Schema.TextField(FieldName.of("user:" + field).as(attribute), weight, false, false, false, null);schema.addField(textField);weight *= 3;continue;}}}IndexDefinition rule = new IndexDefinition(IndexDefinition.Type.JSON).setLanguage("chinese").setPrefixes(new String[]{key});jedis.ftCreate(indexName,IndexOptions.defaultOptions().setDefinition(rule),schema);return true;} catch (Exception e){logger.error("create redis search index failed", e);return false;}}}

测试其中一个接口,效果如下

八、写在文末

RedisJson是Redis扩展功能中的重要数据结构,基于RedisJson结构可以在实际业务中巧妙处理一些疑难杂症,让程序得到很好的灵活性和扩展性,值得深入研究和学习,本篇到此结束,感谢观看,

相关文章:

【微服务】RedisSearch 使用详解

目录 一、RedisJson介绍 1.1 RedisJson是什么 1.2 RedisJson特点 1.3 RedisJson使用场景 1.3.1 数据结构化存储 1.3.2 实时数据分析 1.3.3 事件存储和分析 1.3.4 文档存储和检索 二、当前使用中的问题 2.1 刚性数据库模式限制了敏捷性 2.2 基于磁盘的文档存储导致瓶…...

第三章 栈、队列和数组

第三章 栈、队列、数组 栈栈的基本概念栈的顺序实现栈的链接实现栈的简单应用和递归 队列队列的基本概念队列的顺序实现队列的链接实现 数组数组的逻辑结构和基本运算数组的存储结构矩阵的压缩存储 小试牛刀 栈和队列可以看作是特殊的线性表&#xff0c;是运算受限的线性表 栈 …...

使用GitLab CI/CD 定时运行Playwright自动化测试用例

创建项目并上传到GitLab npm init playwright@latest test-playwright # 一路enter cd test-playwright # 运行测试用例 npx playwright test常用指令 # Runs the end-to-end tests. npx playwright test# Starts the interactive UI mode. npx playwright...

Suricata + Wireshark离线流量日志分析

目录 一、访问一个404网址&#xff0c;触发监控规则 1、使用python搭建一个虚拟访问网址 2、打开Wireshark,抓取流量监控 3、在Suricata分析数据包 流量分析经典题型 入门题型 题目&#xff1a;Cephalopod(图片提取) 进阶题型 题目&#xff1a;抓到一只苍蝇(数据包筛选…...

JMeter基础 —— 使用Badboy录制JMeter脚本!

1、使用Badboy录制JMeter脚本 打开Badboy工具开始进行脚本录制&#xff1a; &#xff08;1&#xff09;当我们打开Badboy工具时&#xff0c;默认就进入录制状态。 如下图&#xff1a; 当然我们也可以点击录制按钮进行切换。 &#xff08;2&#xff09;在地址栏中输入被测地…...

3D孪生场景搭建:3D漫游

上一篇 文章介绍了如何使用 NSDT 编辑器 制作模拟仿真应用场景&#xff0c;今天这篇文章将介绍如何使用NSDT 编辑器 设置3D漫游。 1、什么是3D漫游 3D漫游是指基于3D技术&#xff0c;将用户带入一个虚拟的三维环境中&#xff0c;通过交互式的手段&#xff0c;让用户可以自由地…...

三、综合——计算机应用基础

文章目录 一、计算机概述二、计算机系统的组成三、计算机中数据的表示四、数据库系统五、多媒体技术5.1 多媒体的基本概念5.2 多媒体计算机系统组成5.3 多媒体关键硬件一、计算机概述 1854 年,英国数学家布尔(George Boo1e,1824-1898 年)提出了符号逻辑的思想,数十年后形成了…...

【Redis】SpringBoot整合redis

文章目录 一、SpringBoot整合二、RedisAutoConfiguration自动配置类1、整合测试一下 三、自定义RedisTemplete1、在测试test中使用自定义的RedisTemplete2、自定义RedisTemplete后测试 四、在企业开发中&#xff0c;大部分情况下都不会使用原生方式编写redis1、编写RedisUtils代…...

竞赛选题 深度学习 python opencv 火焰检测识别 火灾检测

文章目录 0 前言1 基于YOLO的火焰检测与识别2 课题背景3 卷积神经网络3.1 卷积层3.2 池化层3.3 激活函数&#xff1a;3.4 全连接层3.5 使用tensorflow中keras模块实现卷积神经网络 4 YOLOV54.1 网络架构图4.2 输入端4.3 基准网络4.4 Neck网络4.5 Head输出层 5 数据集准备5.1 数…...

Python Parser 因子计算性能简单测试

一直以来&#xff0c;Python 都在量化金融领域扮演着至关重要的角色。得益于 Python 强大的库和工具&#xff0c;用户在处理金融数据、进行数学建模和机器学习时变得更加便捷。但作为一种解释性语言&#xff0c;相对较慢的执行速度也限制了 Python 在一些需要即时响应的场景中的…...

【java学习】特殊流程控制语句(8)

文章目录 1. break语句2. continue语句3. return语句4. 特殊流程语句控制说明 1. break语句 break语句用于终止某个语句块的执行&#xff0c;终止当前所在循环。 语法结构&#xff1a; {  ......     break;     ...... } 例子如下&#xff1a; &#xff08;1&…...

pyinstaller 使用

python 打包不依赖于系统环境的应用总结 【pyd库和pyinstaller可执行程序的区别: 在实际开发中&#xff0c;对于多人协作的大型项目&#xff0c; 或者是基于支持Python的商业软件的二次开发等&#xff0c; 如果将py脚本打包成exe可执行文件&#xff0c;不仅不方便调用&#xff…...

ELK集群 日志中心集群

ES&#xff1a;用来日志存储 Logstash:用来日志的搜集&#xff0c;进行日志格式转换并且传送给别人&#xff08;转发&#xff09; Kibana:主要用于日志的展示和分析 kafka Filebeat:搜集文件数据 es-1 本地解析 vi /etc/hosts scp /etc/hosts es-2:/etc/hosts scp /etc…...

有哪些适合初级程序员看的书籍?

1、《C Primer Plus》&#xff08;中文版名《C Primer Plus&#xff08;第五版&#xff09;》&#xff09; 作者&#xff1a;Stephen Prata 该书以C语言为例&#xff0c;详细介绍了编程语言的基础知识、控制结构、函数、指针、数组、字符串、结构体等重要概念。并且&#xff0…...

uniapp iosApp H5+本地文件操作(写入修改删除等)

h5 地址 html5plus 以csv文件为例&#xff0c;写入读取保存修改删除文件内容&#xff0c;传输文件等 1.save 文件保存 function saveCsv(data,pathP,path){// #ifdef APP-PLUSreturn new Promise((resolve, reject) > {plus.io.requestFileSystem( plus.io.PUBLIC_DOCUMEN…...

蓝桥杯 字符串和日期

有一个类型的题目是找到输出图形的规律&#xff0c;然后将其实现。观察下面的图形。你想想你该怎么输出这个图形呢? ABBB#include<stdio.h> int main(){printf(" A\n");printf("BBB\n");return 0; }那么&#xff0c;对于如下的图形&#xff1a; ABB…...

Vue13 监视属性

监视属性 当被监视的属性发生变化时&#xff0c;执行定义的函数 监视属性watch&#xff1a; 1.当被监视的属性变化时, 回调函数自动调用, 进行相关操作 2.监视的属性必须存在&#xff0c;才能进行监视&#xff01;&#xff01; 3.监视的两种写法&#xff1a; (1).new Vue时传入…...

会员商城小程序的作用是什么

随着消费升级、用户消费习惯改变及互联网电商高速发展冲击下&#xff0c;传统线下经营商家面临不少痛点&#xff0c;产品销售难、经营营销难、客户管理难等&#xff0c;线下流量匮乏、受地域限制且各方面管理繁琐&#xff0c;线上成为众商家增长赋能的方式。 对商家来说&#x…...

排序算法——希尔排序

一、介绍: 希尔排序是一种可以减少插入排序中数据比较次数的排序算法&#xff0c;加速算法的进行&#xff0c;排序的原则是将数据区分为特定步长的小区块&#xff0c;然后以插入排序算法对小区块内部进行排序&#xff0c;经历过一轮排序则减少步长&#xff0c;直到所有数据都排…...

SpringBoot项目整合MybatisPlus持久层框架+Druid数据库连接池

前言 之前搭建SpringBoot项目工程&#xff0c;所使用的持久层框架不是Mybatis就是JPA&#xff0c;还没试过整合MybatisPlus框架并使用&#xff0c;原来也如此简单。在此简单记录一下在SpringBoot项目中&#xff0c;整合MybatisPlus持久层框架、Druid数据库连接池的过程。 一、…...

导致 JVM 内存泄露的 ThreadLocal 详解

为什么要有 ThreadLocal 当我们在学习JDBC时获取数据库连接时&#xff0c;每次CRUD的时候都需要再一次的获取连接对象&#xff0c;并把我们的sql交给连接对象实现操作。 在实际的工作中&#xff0c;我们不会每次执行 SQL 语句时临时去建立连接&#xff0c;而是会借助数据库连接…...

使用预约小程序app有什么方便之处

一、用户人群广&#xff1a;无论是老年人、残疾人还是上班族&#xff0c;只要有需要&#xff0c;都可以通过该小程序轻松预约服务。例如&#xff0c;行动不便的老年人或残疾人&#xff0c;可以通过小程序约家政服务、医疗护理等服务&#xff0c;省去了亲自前往服务场所的麻烦。…...

【转】ubuntu 安装 OpenCv 4.6脚本 installOCV.sh

摘自 https://github.com/opencv/opencv/issues/22132 好东西&#xff0c;收一下。 installOCV.sh#! /bin/bash VER4.6.0 PYTHON_VERSION3.8 CORES2 echo "Script for installing the OpenCV $VER on Ubuntu 18.04 LTS" echo "Updating the OS..." sudo …...

Android 视图动画与属性动画的区别

Android的视图动画和属性动画在功能和使用上有一些明显的区别。 视图动画主要作用于视图&#xff0c;实现如缩放、旋转等效果。这种动画效果相对固定&#xff0c;只能应用于视图对象&#xff0c;且只能改变视图的大小和位置&#xff0c;而不能真正改变视图的属性。视图动画在A…...

Springboot——jxls实现同sheet多个列表展示

文章目录 前言制定模板1、限定模板数据的范围2、设定报表展示项 编写测试类1、将xls模板文件放于 resource 下的 doc文件夹中2、导入依赖文件3、编写接口和导出逻辑 效果预览结论 前言 在之前的博客中Springboot——使用jxls实现excel模板导出excel&#xff0c;具体说明了jxls…...

分布式软件架构——服务端缓存的三种属性

服务端缓存 在透明多级分流系统中&#xff0c;我们以流量从客户端中发出开始&#xff0c;以流量到达服务器集群中真正处理业务的节点结束。一起探索了在这个过程中与业务无关的一些通用组件&#xff0c;包括DNS、CDN、客户端缓存&#xff0c;等等。 实际上&#xff0c;服务端缓…...

Flink之Watermark策略代码模板

方式作用WatermarkStrategy.noWatermarks()不生成watermarkWatermarkStrategy.forMonotonousTimestamps()紧跟最大事件时间watermark生成策略WatermarkStrategy.forBoundedOutOfOrderness()允许乱序watermark生成策略WatermarkStrategy.forGenerator()自定义watermark生成策略 …...

ubuntu 安装postgresql,增加VECTOR向量数据库插件 踏坑详细流程

PGSQL安装&#xff0c;删除&#xff0c;运行&#xff0c;修改密码流程 Ubuntu18.04安装与配置postgresql含远程连接教程&#xff08;含踩坑记录&#xff09;_sudo apt-get install postgresql-CSDN博客 详细安装流程以上博客&#xff0c;自己也记录下 安装vector扩展连接 声明…...

基于Springboot实现影视影院订票选座管理系统【项目源码+论文说明】分享

基于Springboot实现影视影院订票选座管理系统演示 摘要 本论文主要论述了如何使用JAVA语言开发一个影城管理系统 &#xff0c;本系统将严格按照软件开发流程进行各个阶段的工作&#xff0c;采用B/S架构&#xff0c;面向对象编程思想进行项目开发。在引言中&#xff0c;作者将论…...

mysql批量插入数据,跳过唯一索引报错

数据准备 DROP TABLE IF EXISTS user1; CREATE TABLE user1 ( id INT NOT NULL AUTO_INCREMENT, name VARCHAR(45) NULL, age INT(3) NOT NULL, PRIMARY KEY (id), UNIQUE INDEX u_name (name));insert into user1(name, age) values (zhangshan, 18), (lisi, 19);1. INSERT I…...