# Redis-cplus-cplus-Parser **Repository Path**: liuhaodon/redis-cplus-cplus-parse ## Basic Information - **Project Name**: Redis-cplus-cplus-Parser - **Description**: 帮助C++开发者快速入门redis-cplus-cplus - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 1 - **Created**: 2025-04-08 - **Last Updated**: 2025-07-12 ## Categories & Tags **Categories**: Uncategorized **Tags**: C语言, Cpp, Redis ## README # Redis-cplus-cplus库使用指南 ## 项目宗旨 本项目旨在帮助C++开发者快速掌握Redis-cplus-cplus库的基本使用。 ## 安装步骤 ### 安装redis-cplus-cplus库(Linux环境) ```bash git clone https://github.com/sewenew/redis-plus-plus.git ``` ### 安装依赖库(Linux环境) #### Ubuntu系统 ```bash apt install libhiredis-dev ``` #### CentOS系统 ```bash yum install hiredis-devel.x86_64 ``` ### 编译安装redis-cplus-cplus ```bash cd redis-plus-plus mkdir build cd build cmake .. make sudo make install ``` ### 安装结果查询 若完成上述操作,可查询当前系统存放redis++各种库的路径: ```bash find /usr -name 'redis++*' ``` 查询hiredis库路径: ```bash find /usr -name 'libhiredis*' ``` ## 编译技巧 编译使用了redis相关接口的程序时,需要指定链接的静态库redis和libhiredis。 以Ubuntu 22.04为例,redis的静态库路径为:`/usr/local/lib/libredis++.a`,libhiredis的路径为:`/usr/lib/x86_64-linux-gnu/libhiredis.a` ,当然你也可以使用`find`命令查找路径。 ### 建立软链接 在项目目录中,建立redis静态库的软链接: ```bash ln -s /usr/local/lib/libredis++.a libredis.a ``` 建立hiredis静态库的软链接: ```bash ln -s /usr/lib/x86_64-linux-gnu/libhiredis.a libhiredis.a ``` 编译Makefile时可以缩短`-l`路径。 ### 删除软链接 ```bash unlink 软连接名称 ``` ### 引入redis++头文件 路径:`/usr/local/include/sw/redis++/redis++.h` ## Redis基本操作 ### set和get #### 函数原型 ```cpp // set函数原型 QueuedRedis& set(const StringView &key, const StringView &val, ...); // get函数原型 OptionalString get(const sw::redis::StringView &key); ``` 无需关注`...`代表的参数,可以缺省,暂时不关注。 #### 参数介绍 `key` 是redis的命令`set`后跟的键,`val` 同理,用于设置键值对,类型为`string`。 #### 示例代码 ```cpp #include #include int main() { sw::redis::Redis redis("tcp://127.0.0.1:6379"); std::string result = redis.ping(); std::cout << result << std::endl; redis.flushall(); { printf("开始执行get、set命令了\n"); if (!redis.set("user", "12345678")) { std::cerr << "set失败!" << std::endl; return -1; } auto val1 = redis.get("user"); if (val1) { std::cout << *val1 << std::endl; } } return 0; } ``` ### exists和del #### 函数原型 ```cpp // exists函数原型 long long exists(const StringView &key); // del函数原型 long long del(const StringView &key); template long long del(std::initializer_list il); ``` #### 参数介绍 `key` 是redis的命令`exists`和`del`后跟的键,用于判断键是否存在和删除键。 #### 测试示例 ```cpp #include #include int main() { sw::redis::Redis redis("tcp://127.0.0.1:6379"); { printf("开始执行exists命令了\n"); long long ret = redis.exists({"user", "pass", "data"}); std::cout << "exists command result: " << ret << std::endl; printf("--------------------------------\n"); } { printf("开始执行del命令了\n"); // 删除单个 printf("删除单个key\n"); long long ret = redis.del("pass"); std::cout << "del command result: " << ret << std::endl; printf("删除多个key\n"); ret = redis.del({"user", "data"}); std::cout << "del command result: " << ret << std::endl; printf("--------------------------------\n"); } return 0; } ``` ### keys #### 函数原型 ```cpp template void Redis::keys(const StringView &pattern, Output output); ``` #### 参数介绍 - `pattern`:表示键的匹配规则。 - `output`:本质是 C++ STL 中的插入迭代器 `std::back_insert_iterator`,可通过 `std::back_inserter(container)` 函数构造,用于将查询结果插入到指定容器(需支持 `push_back` 操作)。 #### 测试示例 ```cpp #include #include #include #include int main() { sw::redis::Redis redis("tcp://127.0.0.1:6379"); { printf("开始执行keys了\n"); redis.flushall(); redis.set("k1", "111"); redis.set("k2", "222"); redis.set("k3", "333"); redis.set("k4", "444"); std::vector rets; auto it = std::back_inserter(rets); redis.keys("*", it); for (auto x : rets) { std::cout << x << std::endl; } printf("--------------------------------\n"); } return 0; } ``` ### expires和ttl #### 函数原型 ```cpp // expires函数原型 bool Redis::expire(const StringView &key, const std::chrono::seconds &timeout); // ttl函数原型 long long ttl(const StringView &key); ``` #### 参数介绍 - `key`:是要设置的键。 - `timeout`:是要设置的键的过期时间,单位为秒。 #### 示例代码 ```cpp #include #include #include #include int main() { sw::redis::Redis redis("tcp://127.0.0.1:6379"); { // 设置5秒后过期 redis.expire("k1", std::chrono::seconds(5)); // 获取指定key剩余过期时间 long long sec = redis.ttl("k1"); while (sec--) { std::cout << "k1剩余过期时间: " << sec << std::endl; sleep(1); } auto ret = redis.get("k1"); if (ret) { std::cout << "val: " << *ret << std::endl; } else { printf("k1已过期!\n"); } printf("--------------------------------\n"); } return 0; } ``` ## string类型 ### 备注:基本指令中出现过的不再赘述 ### mset和mget #### 函数原型 ```cpp // mset函数原型 void Redis::mset(Input first, Input last); // mget函数原型 void mget(std::initializer_list il, Output output) ``` #### 参数介绍 - `mset`:Input表示的输入迭代器类型,可以传递容器的迭代器begin-end - `mget`:il可以传入std::make_pair(string,stirng)类型的参数,output是输出迭代器,可以使用back_inserter()函数构造的返回值 #### 示例代码 ```cpp void unity1(Redis &redis) { printf("开始测试string类型了\n"); printf("开始测试mset\n"); redis.flushall(); std::vector> kvs = {{"u1", "张三"}, {"u2", "李四"}}; redis.mset(kvs.begin(), kvs.end()); std::vector vals; auto it = std::back_inserter(vals); redis.mget({"u1", "u2"}, it); for (auto &str : vals) { if (str.has_value()) std::cout << str.value() << std::endl; } printf("---------------------\n"); } ``` ### setnx #### 函数原型 ```cpp bool setnx(const StringView &key, const StringView &val); ``` #### 参数介绍 - `key`:设置的key,等同于set的key - `val`:设置的val,等同于set的val #### 示例代码 ```cpp void unity2(Redis& redis) { printf("开始执行setnx命令\n"); //u1已存在 bool ret = redis.setnx("u1", "王五"); if (ret == false) { std::cerr << "设置key:u1失败,redis中已存在该key" << std::endl; } else { std::cerr << "设置u1 :王五 成功!" << std::endl; } ret = redis.setnx("u3", "王五"); if (ret == false) { std::cerr << "设置key:u3失败,redis中已存在该key" << std::endl; return; } else { std::cerr << "设置u3 :王五 成功!" << std::endl; } } ``` ### append和strlen #### 函数原型 ```cpp long long append(const StringView &key, const StringView &str); long long strlen(const StringView &key); ``` #### 参数介绍 - `append`:设置的key,等同于set的key,str表示要向key对应的val追加的字符串,函数返回追加成功后的字符串长度 - `strlen`:设置的key,等同于set的key,返回key对应的val字符串的实际长度 #### 示例代码 ```cpp void unity3(Redis &redis) { printf("开始执行append和strlen命令\n"); redis.set("k1", "hello"); OptionalString val = redis.get("k1"); long long len = redis.strlen("k1"); if (val.has_value()) std::cout << "val : " << val.value() << std::endl; std::cout << "append前的长度: " << len << std::endl; len = redis.append("k1", "word"); std::cout << "append后的长度: " << len << std::endl; printf("--------------------------\n"); } ``` #### 测试结果 ```cpp 开始执行append和strlen命令 val : hello append前的长度: 5 append后的长度: 9 ``` ### getrange和setrange #### 函数原型 ```cpp std::string getrange(const StringView &key, long long start, long long end); long long setrange(const StringView &key, long long offset, const StringView &val); ``` #### 参数介绍 - `append`:设置的key,等同于set的key,start表示要截取的起始位置,end表示要截取的结束位置 - `strlen`:设置的key,等同于set的key,offset表示从哪里开始覆盖?val表示覆盖的值,返回设置完成后key对应的val字符串的实际长度 #### 示例代码 ```cpp void unity4(Redis& redis) { printf("开始执行setrange和getrange命令\n"); redis.flushall(); redis.set("k1", "今天天气真好!"); std::string s = redis.getrange("k1", 0, 2); std::cout << "截取后的字串为: " << s << std::endl; long long ret = redis.setrange("k1", 0, "明天见!"); std::cout << "setrange ret = " << ret << std::endl; OptionalString val = redis.get("k1"); if (val.has_value()) std::cout << "val : " << val.value() << std::endl; printf("--------------------------\n"); } ``` ## Hash类型 ### 备注:基本指令中出现过的不再赘述 ### hset && hget #### 函数原型 ```cpp long long hset(const StringView &key, const std::pair &item); OptionalString hget(const StringView &key, const StringView &field); ``` #### 参数介绍 - `hset`:key类似于设置的哈希表的变量名,item中的pair的第一个参数是这个哈希表中的key值,另外一个就是val值 - `hget`:key类似于设置的哈希表的变量名,filed就是这个哈希表中的key值,返回对应的val值(如果有) #### 示例代码 ```cpp void unity1(Redis &redis) { printf("开始执行hset和hget了\n"); redis.flushall(); StringView table_name = "user"; long long n = redis.hset(table_name, std::make_pair("id", "{name: 张三\r\nage: 18\r\n}")); std::cout << "hset command res : " << n << std::endl; OptionalString res = redis.hget(table_name,"id"); if(res.has_value()) std::cout<<"hget command res : "< res; auto it = std::back_inserter(res); redis.hkeys("user", it); if (!res.empty()) { for (auto &x : res) { std::cout << "key-->" << x << std::endl; } std::cout << "\n"; } else std::cout << "user中没有key" << std::endl; printf("---------------------------\n"); res.clear(); it = std::back_inserter(res); redis.hvals("user", it); if (!res.empty()) { for (auto &x : res) { std::cout << x << std::endl; } std::cout << "\n"; } else std::cout << "user中没有val" << std::endl; printf("---------------------------\n"); int n = redis.hlen("user"); std::cout << "hlen command res : " << n << std::endl; res.clear(); it = std::back_inserter(res); redis.hgetall("user", it); if (!res.empty()) { for (auto &x : res) { std::cout << x << std::endl; } std::cout << "\n"; } else std::cout << "user中没有key--val键值对" << std::endl; printf("---------------------------\n"); } ``` ## List类型 ### 备注:基本指令中出现过的不再赘述 ### lpush && lpop #### 函数原型 ```cpp // 头插元素到列表 void lpush(const StringView &key, const StringView &value); // 从列表头部弹出元素 OptionalString lpop(const StringView &key); ``` #### 参数介绍 - `lpush`:`key` 是列表的名称,`value` 是要插入到列表头部的值。 - `lpop`:`key` 是列表的名称,函数返回从列表头部弹出的值,如果列表为空则返回空。 #### 示例代码 ```cpp void unity1(Redis &redis) { printf("开始执行lpush和lpop了\n"); // 头插 for (int i = 1; i <= 5; i++) { redis.lpush("ids", std::to_string(i)); } int len = redis.llen("ids"); while (len--) { OptionalString val = redis.lpop("ids"); if (val.has_value()) std::cout << val.value() << std::endl; } printf("-------------------------\n"); } ``` ### lrange #### 函数原型 ```cpp // 获取列表指定范围的元素 template void lrange(const StringView &key, long long start, long long end, Output output); ``` #### 参数介绍 - `lrange`:`key` 是列表的名称,`start` 是起始索引,`end` 是结束索引,`output` 是用于存储结果的容器的插入迭代器。 #### 示例代码 ```cpp void unity2(Redis &redis) { printf("开始执行lrange了\n"); redis.flushall(); for (int i = 1; i <= 5; i++) { redis.lpush("ids", std::to_string(i)); } std::vector res; auto it = std::back_inserter(res); redis.lrange("ids", 0, redis.llen("ids"), it); for (auto &x : res) std::cout << x << "\t"; std::cout << "\n"; printf("--------------------------\n"); } ``` ### rpush && rpop #### 函数原型 ```cpp // 尾插元素到列表 void rpush(const StringView &key, const StringView &value); // 从列表尾部弹出元素 OptionalString rpop(const StringView &key); ``` #### 参数介绍 - `rpush`:`key` 是列表的名称,`value` 是要插入到列表尾部的值。 - `rpop`:`key` 是列表的名称,函数返回从列表尾部弹出的值,如果列表为空则返回空。 #### 示例代码 ```cpp void unity3(Redis &redis) { redis.flushall(); for (int i = 1; i <= 5; i++) { redis.rpush("ids", std::to_string(i)); } int len = redis.llen("ids"); while (len--) { OptionalString elem = redis.rpop("ids"); if (elem.has_value())std::cout << elem.value() << "\t"; } printf("--------------------------\n"); } ``` ### lindex && linsert #### 函数原型 ```cpp // 获取列表指定索引的元素 OptionalString lindex(const StringView &key, long long index); // 在列表中指定元素前后插入新元素 long long linsert(const StringView &key, InsertPosition position, const StringView &pivot, const StringView &value); ``` #### 参数介绍 - `lindex`:`key` 是列表的名称,`index` 是要获取元素的索引,函数返回指定索引的元素,如果索引越界则返回空。 - `linsert`:`key` 是列表的名称,`position` 是插入位置(如 `InsertPosition::AFTER` 表示在指定元素后插入),`pivot` 是基准元素,`value` 是要插入的新元素,函数返回插入后列表的长度。 #### 示例代码 ```cpp void unity4(Redis &redis) { printf("开始执行lindex和linsert了\n"); redis.flushall(); for (int i = 1; i <= 5; i++) { redis.rpush("ids", std::to_string(i)); } OptionalString e1 = redis.lindex("ids", 0); OptionalString e2 = redis.lindex("ids", 1); OptionalString e3 = redis.lindex("ids", 2); OptionalString e4 = redis.lindex("ids", 3); OptionalString e5 = redis.lindex("ids", 4); std::cout< res; auto it = std::back_inserter(res); int len = redis.linsert("ids",InsertPosition::AFTER,"1","100"); int end = redis.llen("ids"); redis.lrange("ids",0,end,it); for(auto& x : res) std::cout< void smembers(const StringView &key, Output output); ``` #### 参数介绍 - `sadd`:`key` 是集合的名称,`member` 是要添加的元素,支持重复调用添加多个元素,返回实际新增的元素数量(去重后)。 - `smembers`:`key` 是集合的名称,`output` 是用于存储结果的容器的插入迭代器(如 `std::back_inserter`)。 #### 示例代码 ```cpp void unity1(Redis &redis) { printf("开始测试sadd和smembers\n"); redis.flushall(); // 向集合"myset"中添加元素 long long ret = redis.sadd("myset", "helloset"); ret += redis.sadd("myset", "2"); ret += redis.sadd("myset", "3"); ret += redis.sadd("myset", "4"); std::cout << "sadd执行结果: " << ret << std::endl; // 输出4,因无重复元素 // 查询集合中的所有元素 std::vector res; auto it = std::back_inserter(res); redis.smembers("myset", it); for (auto &s : res) { std::cout << s << std::endl; // 输出集合中的所有元素 } std::cout << "---------------------" << std::endl; } ``` ### sismember && scard #### 函数原型 ```cpp // 判断元素是否存在于集合中 bool sismember(const StringView &key, const StringView &member); // 获取集合中元素的个数 long long scard(const StringView &key); ``` #### 参数介绍 - `sismember`:`key` 是集合的名称,`member` 是待判断的元素,返回 `true`(存在)或 `false`(不存在)。 - `scard`:`key` 是集合的名称,返回集合中元素的数量。 #### 示例代码 ```cpp void unity2(Redis &redis) { printf("开始测试sismember和scard了\n"); redis.flushall(); // 向集合中添加元素 redis.sadd("myset", "1"); redis.sadd("myset", "2"); redis.sadd("myset", "3"); redis.sadd("myset", "4"); // 判断元素是否存在 bool flag = redis.sismember("myset", "1"); std::cout << "sismember执行结果: " << flag << std::endl; // true flag = redis.sismember("myset", "10"); std::cout << "sismember执行结果: " << flag << std::endl; // false // 获取集合元素个数 std::cout << "set的元素个数: " << redis.scard("myset") << std::endl; // 输出4 } ``` ### spop && smove && srem #### 函数原型 ```cpp // 从集合中随机弹出一个元素 OptionalString spop(const StringView &key); // 将元素从一个集合移动到另一个集合 bool smove(const StringView &source, const StringView &destination, const StringView &member); // 从集合中删除指定元素 long long srem(const StringView &key, const StringView &member); ``` #### 参数介绍 - `spop`:`key` 是集合的名称,返回弹出的元素(`OptionalString`,若集合为空则无值)。 - `smove`:`source` 是源集合名称,`destination` 是目标集合名称,`member` 是要移动的元素,成功返回 `true`。 - `srem`:`key` 是集合的名称,`member` 是要删除的元素,返回实际删除的元素数量(1或0)。 #### 示例代码 ```cpp void unity3(Redis &redis) { printf("开始测试spop和smove,Srem了\n"); redis.flushall(); // 向"myset"添加元素 redis.sadd("myset", "1"); redis.sadd("myset", "2"); redis.sadd("myset", "3"); redis.sadd("myset", "40"); // 随机弹出一个元素 OptionalString opstr = redis.spop("myset"); if (opstr.has_value()) { std::cout << "spop弹出元素: " << opstr.value() << std::endl; // 输出随机元素(如"40") } // 创建目标集合"myset2"并移动元素 redis.sadd("myset2", "1"); bool flag = redis.smove("myset", "myset2", "40"); // 假设"40"存在于myset中 std::cout << "smove执行结果: " << flag << std::endl; // true(移动成功) // 删除元素 long long ret3 = redis.srem("myset", "1"); std::cout << "srem删除1个元素: " << ret3 << std::endl; // 1(若"1"存在) // 验证集合内容 std::vector res; auto it = std::back_inserter(res); redis.smembers("myset", it); for (auto &s : res) { std::cout << "myset剩余元素: " << s << std::endl; // 输出剩余元素 } } ``` ### 集合操作总结 Set类型支持元素的唯一性存储,常用操作包括: - **添加元素(`sadd`)**:去重后返回新增数量。 - **查询元素(`smembers`)**:获取所有元素,需通过插入迭代器存储结果。 - **判断存在(`sismember`)**:高效判断元素是否存在,时间复杂度为O(1)。 - **弹出/移动/删除(`spop`/`smove`/`srem`)**:支持随机弹出、跨集合移动及指定元素删除。 ## ZSet类型(有序集合) ### 备注:基本指令中出现过的不再赘述 ### zadd && zcard #### 函数原型 ```cpp // 向有序集合中添加一个或多个成员,或者更新已存在成员的分数 long long zadd(const StringView &key, const StringView &member, double score); template long long zadd(const StringView &key, Input first, Input last); // 获取有序集合的成员数量 long long zcard(const StringView &key); ``` #### 参数介绍 - **`zadd` 单元素添加重载**: - `key`:代表有序集合的名称。在Redis里,这是用于标识不同有序集合的唯一键。例如,若要维护一个游戏玩家的排行榜,`key` 可以设为 `game_ranking`。 - `member`:是要添加到有序集合里的成员。在上述游戏排行榜的例子中,`member` 可以是玩家的ID。 - `score`:此为成员对应的分数,有序集合会依据这个分数对成员进行排序。对于游戏排行榜,`score` 可以是玩家的得分。该函数会返回实际新增的成员数量,若成员已存在,会更新其分数但不增加返回值。 - **`zadd` 批量添加重载**: - `key`:同样是有序集合的名称。 - `first` 和 `last`:这两个参数是迭代器,指定了一个包含成员 - 分数对的范围。一般使用 `std::vector>` 这种容器,其中 `std::pair` 的第一个元素是成员,第二个元素是分数。函数会遍历这个范围,将其中的成员 - 分数对添加到有序集合中,返回实际新增的成员数量。 - **`zcard`**: - `key`:有序集合的名称。调用该函数时,它会返回指定有序集合中成员的数量。 #### 示例代码 ```cpp void unity1(Redis &redis) { printf("开始执行zadd和zcard命令了\n"); redis.flushall(); // 单个数据添加 long long ret = redis.zadd("z1", "hello", 10); std::cout << "单个数据zadd : " << ret << std::endl; // 批量zadd redis.flushall(); std::vector> inputs = {{"m1", 10}, {"m2", 20}, {"m3", 30}}; ret = redis.zadd("z1", inputs.begin(), inputs.end()); std::cout << "批量zadd : " << ret << std::endl; std::cout << "-------------------------" << std::endl; ret = redis.zcard("z1"); std::cout << "集合中元素个数为: " << ret << std::endl; } ``` ### zcount && zrange #### 函数原型 ```cpp // 计算有序集合中指定分数区间的成员数量 long long zcount(const StringView &key, const BoundedInterval &interval); // 通过索引区间返回有序集合指定区间内的成员 template void zrange(const StringView &key, long long start, long long stop, Output output); ``` #### 参数介绍 - **`zcount`**: - `key`:有序集合的名称。 - `interval`:这是一个 `BoundedInterval` 类型的对象,用于指定分数区间。`BoundedInterval` 有不同的边界类型(`BoundType`),包括开区间、闭区间、左开右闭和左闭右开。例如,`sw::redis::BoundedInterval bound(10.0, 20.0, BoundType::CLOSED)` 表示一个闭区间 `[10.0, 20.0]`。该函数会返回指定有序集合中分数在这个区间内的成员数量。 - **`zrange`**: - `key`:有序集合的名称。 - `start` 和 `stop`:这两个参数是索引值,用于指定成员的范围。索引从 0 开始,`start` 是起始索引,`stop` 是结束索引。可以使用负数索引,-1 表示最后一个成员,-2 表示倒数第二个成员,以此类推。 - `output`:这是一个输出迭代器,用于存储查询结果。通常使用 `std::back_inserter` 来构造,它会将查询到的成员插入到指定的容器中。 #### 示例代码 ```cpp void unity2(Redis &redis) { printf("开始测试zcount和zrange了\n"); redis.flushall(); std::vector> inputs = {{"m1", 10}, {"m2", 20}, {"m3", 30}}; long long ret = redis.zadd("z1", inputs.begin(), inputs.end()); std::cout << "批量zadd : " << ret << std::endl; std::cout << "-------------------------" << std::endl; // BoundType参数可以设置:开区间,闭区间,左开右闭,左闭右开 sw::redis::BoundedInterval bound(10.0, 20.0, BoundType::CLOSED); ret = redis.zcount("z1", bound); std::cout << "zcount: " << ret << std::endl; std::cout << "---------------------------" << std::endl; std::vector res; auto it = std::back_inserter(res); redis.zrange("z1", 0, 2, it); for (auto &s : res) { std::cout << s << std::endl; } } ``` ### zrevrange && zrangebyscore #### 函数原型 ```cpp // 返回有序集中指定区间内的成员,通过索引,分数从高到低排序 template void zrevrange(const StringView &key, long long start, long long stop, Output output); // 通过分数返回有序集合指定区间内的成员 template void zrangebyscore(const StringView &key, const BoundedInterval &interval, Output output); ``` #### 参数介绍 - **`zrevrange`**: - `key`:有序集合的名称。 - `start` 和 `stop`:索引值,用于指定成员的范围,与 `zrange` 类似,但成员会按照分数从高到低排序。 - `output`:输出迭代器,用于存储查询结果。 - **`zrangebyscore`**: - `key`:有序集合的名称。 - `interval`:`BoundedInterval` 类型的对象,用于指定分数区间,与 `zcount` 中的 `interval` 类似。 - `output`:输出迭代器,用于存储查询结果。该函数会返回指定有序集合中分数在 `interval` 范围内的成员,成员按分数从小到大排序。 #### 示例代码 ```cpp void unity3(Redis &redis) { printf("开始测试zrevrange和Zrangebyscore了\n"); redis.flushall(); std::vector> inputs = {{"m1", 10}, {"m2", 20}, {"m3", 5}}; long long ret = redis.zadd("z1", inputs.begin(), inputs.end()); std::cout << "批量zadd : " << ret << std::endl; std::cout << "-------------------------" << std::endl; std::vector res; auto it = std::back_inserter(res); redis.zrevrange("z1", 0, 2, it); for (auto &s : res) { std::cout << s << std::endl; } res.clear(); it = std::back_inserter(res); std::cout << "--------------------" << std::endl; BoundedInterval bound(10.0, 15.0, BoundType::CLOSED); redis.zrangebyscore("z1", bound, it); for (auto &s : res) { std::cout << s << std::endl; } } ``` ### zrem #### 函数原型 ```cpp // 移除有序集合中的一个或多个成员 long long zrem(const StringView &key, const StringView &member); ``` #### 参数介绍 - **`zrem`**: - `key`:有序集合的名称。 - `member`:要从有序集合中移除的成员。该函数会返回实际移除的成员数量,如果成员不存在,返回 0。 #### 示例代码 ```cpp void unity4(Redis &redis) { printf("开始执行zrem命令\n"); redis.flushall(); std::vector> inputs = {{"m1", 10}, {"m2", 20}, {"m3", 5}}; long long ret = redis.zadd("z1", inputs.begin(), inputs.end()); std::cout << "批量zadd : " << ret << std::endl; std::cout << "-------------------------" << std::endl; ret = redis.zrem("z1", "m1"); std::cout << "zrem : " << ret << std::endl; ret = redis.zrem("z1", "m2"); std::cout << "zrem : " << ret << std::endl; ret = redis.zrem("z1", "m3"); std::cout << "zrem : " << ret << std::endl; // 删除一个不存在的值 ret = redis.zrem("z1", "m4"); std::cout << "zrem : " << ret << std::endl; } ``` ### ZSet类型总结 ZSet类型(有序集合)结合了集合的唯一性和排序功能,通过分数对成员进行排序。常用操作包括: - **添加成员(`zadd`)**:支持单个或批量添加成员及其分数,返回新增成员数量。 - **统计成员数量(`zcard`)**:快速获取有序集合中成员的总数。 - **统计分数区间成员数量(`zcount`)**:根据指定的分数区间统计成员数量。 - **获取成员(`zrange`、`zrevrange`、`zrangebyscore`)**:通过索引或分数区间获取成员,支持正序和逆序。 - **移除成员(`zrem`)**:移除指定的成员,返回实际移除的数量。 这些操作使得ZSet在排行榜、热门列表等场景中非常实用。