redis zremove删除不掉【bug】

redis zremove删除不掉【bug】

  • 前言
  • 版权
  • redis zremove删除不掉
    • 错误产生
    • 相关资源
      • EldData
      • EchartsTest
      • DataService
    • 解决
  • 最后

前言

2024-4-12 20:35:21

以下内容源自《【bug】》
仅供学习交流使用

版权

禁止其他平台发布时删除以下此话
本文首次发布于CSDN平台
作者是CSDN@日星月云
博客主页是https://blog.csdn.net/qq_51625007
禁止其他平台发布时删除以上此话

redis zremove删除不掉

测试一

  1. 调用添加数据:testAddData20
  2. 调用修改数据:testUpdateData
  3. 调用删除方法:testRemoveData20

结果:调用删除新的数据,旧的数据就会重新出现

1.
{date=[2024-04-13], rate1=[20], rate2=[20], id=[20]}
2.
true
{date=[2024-04-13], rate1=[22], rate2=[22], id=[20]}
3.
1
{date=[2024-04-13], rate1=[20], rate2=[20], id=[20]}

测试二:

  1. 调用添加数据:testAddData
  2. 调用删除方法:testRemoveData20

结果:删除成功,只有数据完全一样才行

1.
{date=[2024-04-13, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12], rate1=[20, 9, 8, 7, 6, 5, 4, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 3, 2, 1], rate2=[20, 9, 8, 7, 6, 5, 4, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 3, 2, 1], id=[20, 9, 8, 7, 6, 5, 4, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 3, 2, 1]}
2.
1
{date=[2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12], rate1=[9, 8, 7, 6, 5, 4, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 3, 2, 1], rate2=[9, 8, 7, 6, 5, 4, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 3, 2, 1], id=[9, 8, 7, 6, 5, 4, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 3, 2, 1]}

错误产生

为什么可以修改,但是不能删除

在上面的代码中,虽然使用了自定义序列化器和比较方法来实现根据特定条件或属性删除数据,但是在实际操作中,Redis有序集合的remove方法确实只能删除完全相同的数据。

这是因为在Redis的有序集合中,元素是通过score进行排序的,而remove方法是根据元素的值来删除的。如果元素的值完全相同,那么remove方法可以成功删除。但是如果元素的值中的某些属性或条件不同,即使其他属性相同,remove方法也无法删除这样的数据。

因此,如果希望根据特定属性或条件删除数据,可以考虑使用其他数据结构或方法来实现,比如使用Redis的哈希表来存储数据,然后通过特定的属性作为键来删除数据。或者在应用层进行数据的筛选和删除操作,然后再写回Redis中。

不能根据equals方法判断的吗

对于Java中的对象,可以通过重写equals方法来自定义判断两个对象是否相等。但是在Redis中,数据是以字符串或字节数组的形式存储的,并没有对对象的equals方法进行支持。

在Redis中,有序集合的remove方法是根据元素的值来删除的,而不是根据对象的equals方法。只有完全相同的值才可以被成功删除,否则无法删除。

如果希望根据对象的equals方法来判断是否删除数据,通常需要在应用层进行操作,先获取到数据再进行比较,然后再删除数据。或者可以使用其他数据结构或方法来实现根据对象的equals方法来删除数据。Redis本身并不提供根据对象的equals方法进行删除的功能。

应该是与序列化和反序列化有关。

相关资源

EldData

package com.jsss.echarts.entity;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;import java.sql.Date;
import java.util.Objects;@Data
@NoArgsConstructor
@AllArgsConstructorpublic class EldData {String id;Integer rate1;Integer rate2;Date date;public EldData(String id, Date date) {this.id = id;this.date = date;}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;EldData eldData = (EldData) o;return Objects.equals(id, eldData.id) && Objects.equals(date, eldData.date);}@Overridepublic int hashCode() {return Objects.hash(id, date);}@Overridepublic String toString() {return "EldData{" +"rate1=" + rate1 +", rate2=" + rate2 +", date=" + date +'}';}
}

EchartsTest

package com.jsss.echarts.service;import com.jsss.echarts.entity.EldData;
import com.jsss.utils.Constant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;@Service
public class DataService implements Constant {@AutowiredRedisTemplate redisTemplate;//返回数据链表public HashMap<String,ArrayList> searchMap(Integer userId){HashMap<String,ArrayList> map=new HashMap<>();List<EldData> dataList = search(userId);List<String> fieldNames = new ArrayList<>();Class<?> dataClass = EldData.class;// 获取 OldData 类的所有属性名Field[] fields = dataClass.getDeclaredFields();for (Field field : fields) {fieldNames.add(field.getName());map.put(field.getName(),new ArrayList<>());}for (EldData data : dataList) {for (String fieldName : fieldNames) {ArrayList<Object> rowData =map.get(fieldName);try {Field field = dataClass.getDeclaredField(fieldName);field.setAccessible(true);rowData.add(field.get(data));} catch (NoSuchFieldException | IllegalAccessException e) {e.printStackTrace();}map.put(fieldName,rowData);}}return map;}//搜索数据public List<EldData> search(Integer userId) {String key= ELD_DATA +userId;Set set = redisTemplate.opsForZSet().reverseRange(key, 0, 19);// 获取分数最高的20个数据return set !=null?new ArrayList<>(set):new ArrayList<>();}// 将数据存储到有序集合中,分数为日期的时间戳public boolean addData(Integer userId, EldData data) {String key= ELD_DATA +userId;return redisTemplate.opsForZSet().add(key, data,data.getDate().getTime());}// 更新数据,如果数据已存在则会覆盖public boolean updateData(Integer userId, EldData newData) {String key= ELD_DATA +userId;return redisTemplate.opsForZSet().add(key, newData, newData.getDate().getTime());}// 删除指定的数据public long removeData(Integer userId, EldData data) {String key= ELD_DATA +userId;return redisTemplate.opsForZSet().remove(key, data);}@Testpublic void test2() {System.out.println("1.");testAddData20();System.out.println("2.");testUpdateData();System.out.println("3.");testRemoveData();}}

DataService

package com.jsss.echarts.service;import com.jsss.echarts.entity.EldData;
import com.jsss.utils.Constant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;@Service
public class DataService implements Constant {@AutowiredRedisTemplate redisTemplate;//返回数据链表public HashMap<String,ArrayList> searchMap(Integer userId){HashMap<String,ArrayList> map=new HashMap<>();List<EldData> dataList = search(userId);List<String> fieldNames = new ArrayList<>();Class<?> dataClass = EldData.class;// 获取 OldData 类的所有属性名Field[] fields = dataClass.getDeclaredFields();for (Field field : fields) {fieldNames.add(field.getName());map.put(field.getName(),new ArrayList<>());}for (EldData data : dataList) {for (String fieldName : fieldNames) {ArrayList<Object> rowData =map.get(fieldName);try {Field field = dataClass.getDeclaredField(fieldName);field.setAccessible(true);rowData.add(field.get(data));} catch (NoSuchFieldException | IllegalAccessException e) {e.printStackTrace();}map.put(fieldName,rowData);}}return map;}//搜索数据public List<EldData> search(Integer userId) {String key= ELD_DATA +userId;Set set = redisTemplate.opsForZSet().reverseRange(key, 0, 19);// 获取分数最高的20个数据return set !=null?new ArrayList<>(set):new ArrayList<>();}// 将数据存储到有序集合中,分数为日期的时间戳public boolean addData(Integer userId, EldData data) {String key= ELD_DATA +userId;return redisTemplate.opsForZSet().add(key, data,data.getDate().getTime());}// 更新数据,如果数据已存在则会覆盖public boolean updateData(Integer userId, EldData newData) {String key= ELD_DATA +userId;return redisTemplate.opsForZSet().add(key, newData, newData.getDate().getTime());}// 删除指定的数据public long removeData(Integer userId, EldData data) {String key= ELD_DATA +userId;return redisTemplate.opsForZSet().remove(key, data);}}

解决

不知道怎么解决

修改更新业务
先删除旧的,再添加新的
保证只有一个equals对象

   // 将数据存储到有序集合中,分数为日期的时间戳public boolean addData(Integer userId, EldData data) {String key= ELD_DATA +userId;return redisTemplate.opsForZSet().add(key, data,data.getDate().getTime());}// 更新数据,先删除数据,后增加新数据public boolean updateData(Integer userId,EldData oldData,EldData newData) {long res=removeData(userId,oldData);if (res==0){//没有旧数据,就修改失败return false;}return addData(userId, newData);}// 删除指定的数据public long removeData(Integer userId, EldData data) {String key= ELD_DATA +userId;return redisTemplate.opsForZSet().remove(key, data);}

对应的测试方法

    @Testpublic void testUpdateData() {EldData oldData=new EldData(String.valueOf(20),20,20,date);EldData newData=new EldData(String.valueOf(20),22,22,date);System.out.println(dataService.updateData(userId, oldData,newData));testSearchMap();}

测试test1,结果:

1.
{date=[2024-04-13], rate1=[20], rate2=[20], id=[20]}
2.
true
{date=[2024-04-13], rate1=[22], rate2=[22], id=[20]}
3.
1
{date=[], rate1=[], rate2=[], id=[]}

最后

2024-4-12 21:31:23

我们都有光明的未来

祝大家考研上岸
祝大家工作顺利
祝大家得偿所愿
祝大家如愿以偿
点赞收藏关注哦

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

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

相关文章

Ubuntu16.04 CUPS安装与Andoird ndk交叉编译CUPS(待续...)

ubuntu安装cups 在Ubuntu上安装CUPS&#xff08;打印系统&#xff09;的步骤如下&#xff1a; 1、打开终端。 2、更新软件包列表&#xff1a; sudo apt update 3、安装CUPS&#xff1a; sudo apt install cups​​​​​​​ 4、安装foomatic-filters与ghostscript&…

每日一练(力扣)

我的思路是暴力枚举: 情况1:相同&#xff0c;就让子串和原串同时后移继续比较 情况2:不相同&#xff0c;就只让原串后移 public int strStr(String haystack, String needle) {if (haystack.length() < needle.length()){return -1;}for (int i 0; i < h…

HiveSQL基础Day03

回顾总结 hive表的类型 &#xff1a;内部表和外部表 删除内部表会删除表的所有数据 删除外部表只会删除表的元数据&#xff0c;hdfs上的行数据会保留 表的分区和分桶 本质都是对表数据的拆分存储 分区的方式 是通过创建不同的目录来拆分数据 &#xff0c;根据数据本身的内容最为…

K8S哲学 - 常见的资源类型

资源类型 namespace kubectl apply 和 kubectl create kubectl apply是声明式的 和 kubectl create是命令式的对吗 deployment 和 job的区别 k8s 的 lable 的意义

【YUNBEE云贝-进阶课】MySQL8.0性能优化实战培训

众多已经学习过MySQL 8.0 OCP认证专家的课程的同学们对 MySQL 8.0 的安装部署、体系结构、配置监控、用户管理、主从复制、系统运维、MGR等基础操作和动手实验有了一定的学习基础.很多学员反馈希望更进一步提升技术能力、解决工作中碰到的性能问题。 针对MySQL8.0的数据库性能优…

DMA的认识

DMA介绍 Q:什么是DMA&#xff1f; DMA( Direct Memory Access&#xff0c;直接存储器访问 ) 提供在 外设与内存 、 存储器和存储器 、 外设 与外设 之间的 高速数据传输 使用。它允许不同速度的硬件装置来沟通&#xff0c;而不需要依赖于 CPU &#xff0c;在这个时间中&am…

go的标准化error处理

go的标准化error处理 文章目录 go的标准化error处理1、建议这样写错误处理2、怎么优化代码让其不再堆积 1、建议这样写错误处理 // 1 func autn() {var err errorif err ! nil {// handle err}//do stuff }// 2 func a(r *http.Request) error {//err : r.ParseForm()//if er…

算法打卡day34

今日任务&#xff1a; 1&#xff09;62.不同路径 2&#xff09;63.不同路径 II 3&#xff09;复习day10 62.不同路径 题目链接&#xff1a;62. 不同路径 - 力扣&#xff08;LeetCode&#xff09; 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “S…

数据中心的网络架构设计,打造高效、安全的数字底座

数据中心的网络架构设计 一、数据中心网络架构设计原则 网络,作为数据中心的核心支柱,其结构精妙,由众多二层接入设备与少量三层设备共同编织而成。过去,数据中心网络规模有限,仅凭数十台设备的简单互连便能实现信息的畅通无阻。然而,随着技术与应用需求的飞速增长,数据…

Missing artifact org.opencv:opencv:jar:4.10.0 [opencv-4.10.0.jar]

Missing artifact org.opencv:opencv:jar:4.10.0 [opencv-4.10.0.jar] https://mvnrepository.com/artifact/org.opencv/opencv 根本就没有 找了个旧项目的opencv-410.jar修改下opencv-4.10.0.jar放到目录下面就好了 D:\localRepository\org\opencv\opencv\4.10.0 OpenCV-C…

[HDFS 相关Shell命令]

目录 HDFS 相关Shell命令: 相关文件操作命令: HDFS 相关Shell命令: 注意&#xff0c;下述命令中的<path>代表文件或目录的路径&#xff0c;<local_path>代表本地文件系统的路径&#xff0c;而<hdfs_path>代表HDFS上的路径。使用这些命令时&#xff0c;需要…

类的六个默认成员函数(上)

目录 构造函数 析构函数 拷贝构造函数 对于日期&#xff08;Date&#xff09;类&#xff0c;可以通过 Init 公有方法给对象设置日期&#xff0c;但如果每次创建对象时都调用该方法设置信息&#xff0c;未免有点麻烦&#xff0c;那能否在对象创建时&#xff0c;就将信息设置进…

鸿蒙OS开发学习:【第三方库调用】

介绍 本篇Codelab主要向开发者展示了在Stage模型中&#xff0c;如何调用已经上架到[三方库中心]的社区库和项目内创建的本地库。效果图如下&#xff1a; 相关概念 [Navigation]&#xff1a;一般作为Page页面的根容器&#xff0c;通过属性设置来展示页面的标题、工具栏、菜单。…

使用低空无人机图像对树种进行实例分割

在这项试点研究中,利用低空无人机图像开发了一种针对当地树种的机器学习实例分割模型,用于生态调查目的。实例分割包括个体树冠描绘和物种分类。 20 种树种及其相关学名已通过无人机图像进行了训练和收集,用于机器学习过程。为了评估 ML 模型的准确性,半监督分割图像将与已…

政安晨:【Keras机器学习实践要点】(二十七)—— 使用感知器进行图像分类

目录 简介 设置 准备数据 配置超参数 使用数据增强 实施前馈网络&#xff08;FFN&#xff09; 将创建修补程序作为一个层 实施补丁编码层 建立感知器模型 变换器模块 感知器模型 编译、培训和评估模式 政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍…

Lua语法(五)——垃圾回收

参考链接: 系列链接: Lua语法(一) 系列链接: Lua语法(二)——闭包/日期和时间 系列链接: Lua语法(三)——元表与元方法 系列链接: Lua语法(四)——协程 系列链接: Lua语法(五)——垃圾回收 系列链接: Lua语法(六)——面相对象编程 Lua语法 五——垃圾回收 垃圾回收弱引用表__m…

并查集(Union-Find)介绍

并查集是一种树型的数据结构&#xff0c;用于处理一些不相交集合&#xff08;Disjoint Sets&#xff09;的合并及查询问题。它常常在某些图论算法中被使用&#xff0c;比如求解最小生成树的Kruskal算法中就需要使用并查集来判断加入某条边后是否会形成环。在实际应用中&#xf…

2024届数字IC秋招-华为机试-数字芯片-笔试真题和答案(五)(含2022年和2023年)

文章目录 前言1、多比特信号A,时钟域clk_a存在从4’d11到4’d12的变化过程中,若时钟域clk_b直接采用D触发器采样,可能采样到数据是2、Bod由1变成0,Arb会如何变化3、减少片外DRAM的访问,而代之以片内SRAM访问,这样可以降低访问功耗,降低片外DRAM,同时加大片内SRAM能节省…

Spring Boot集成Graphql快速入门Demo

1.Graphql介绍 GraphQL 是一个用于 API 的查询语言&#xff0c;是一个使用基于类型系统来执行查询的服务端运行时&#xff08;类型系统由你的数据定义&#xff09;。GraphQL 并没有和任何特定数据库或者存储引擎绑定&#xff0c;而是依靠你现有的代码和数据支撑。 优势 GraphQL…

【Android】【root remount】adb su如何添加密码校验

前言 客户想在user版本添加su 权限&#xff0c;并实现user版本的root remount功能。 当前思路时执行su时添加密码&#xff0c;如果密码正确设置 sys.变量为true。adb root时判断sys变量为true时&#xff0c;执行root动作。 su 添加密码实现 su.cpp 添加密码部分&#xff1a;…