Redis:查询是否包含某个字符/字符串之三

 上一篇:Redis:查询是否包含某个字符/字符串之二-CSDN博客

摘要:

遍历key,在跟进value的类型遍历value是否包含指定字符串 search_strings ,这里使用redis-py库,默认只能处理utf-8编码,如果存在其他编码会出现问题。

使用decode_responses=True可以顺利的遍历不同类型的value,不使用该参数可以顺利遍历不同编码的key。

正文:

源代码

import redis
import chardet

# 连接到Redis服务器
r = redis.Redis(host=' xx', port=6935, db=9, decode_responses=True)
# r = redis.Redis(host=' xx', port=6935, db=9)


# 假设我们有以下key和它们对应的数据类型
# key1: 字符串
# key2: 列表
# key3: 集合
# key4: 有序集合
# key5: 哈希表

# 函数:根据key的数据类型执行不同的操作
def handle_data_by_type(key, file, search_strings):
    try:
        # 获取key的类型
        data_type = r.type(key)
        # b'string'
        if data_type == 'string':
            # 对于字符串,直接获取并打印
            value = r.get(key)
            # print(f"String: {value}")
            has_attr(value, key, file, search_strings)
        elif data_type == 'list':
            # 对于列表,遍历并打印每个元素
            values = r.lrange(key, 0, -1)  # 获取列表中的所有元素
            for value in values:
                has_attr(value, key, file, search_strings)
                # print(f"List Element: {value}")
        elif data_type == 'set':
            # 对于集合,遍历并打印每个元素(注意集合是无序的)
            members = r.smembers(key)
            for member in members:
                # has_attr(member, key, file, search_strings)
                print(f"Set Member: {member}")
        elif data_type == 'zset':
            # 对于有序集合,遍历并打印每个元素及其分数
            for member, score in r.zscan_iter(key):
                print(f"Sorted Set Member: {member}, Score: {score}")
        elif data_type == 'hash':
            # 对于哈希表,遍历并打印每个字段及其值
            for field in r.hkeys(key):
                # result = chardet.detect(field)
                # encoding = result['encoding']
                value = r.hget(key, field)
                has_attr(value, key, file, search_strings)
                # print(f"Hash Field: {field}, Value: {value}")
        else:
            print(f"Unknown data type for key: {key}")
    except Exception as e:
        print(f"Error processing key: {key}, error: {e}")
    # 示例:处理不同的key


# handle_data_by_type('key1')  # 假设key1是字符串
# handle_data_by_type('key2')  # 假设key2是列表
# handle_data_by_type('key3')  # 假设key3是集合
# handle_data_by_type('key4')  # 假设key4是有序集合
# handle_data_by_type('key5')  # 假设key5是哈希表

# 注意:上面的'key1'到'key5'及其数据类型只是示例,你需要根据实际情况替换它们
def has_attr(value, key, file, search_strings):
    if value:  # 确保value不是None
        # 检查value是否包含任何一个search_strings中的字符串
        for search_string in search_strings:
            if search_string in value:
                # print(f"Key: {key}, Value: {value}, contains: {search_string}")
                file.write(f"Key: {key}, Value: {value}, contains: {search_string}\n")
                break  # 如果已经找到一个匹配的字符串,可以跳出内层循环

if __name__ == '__main__':
    # 连接到Redis服务器
    # r = redis.Redis(host='10.14.177.66', port=6935, db=9, decode_responses=True)

    # 要搜索的字符串列表
    search_strings = ['xxx ']
    # 使用SCAN命令迭代遍历Redis中的所有key
    cursor = '0'

    with open('20240813_1916.txt', 'a') as file:
        while cursor != 0:
            cursor, keys = r.scan(cursor=cursor, match='*', count=10)
            # print(f"Cursor: {cursor}, Keys: {keys}, Length: {len(keys)}")
            for key in keys:
                try:
                    # 尝试将键解码为 UTF-8 字符串
                    decoded_key = key.decode('utf-8')
                    # print(f"Processing key: {key}")
                    handle_data_by_type(decoded_key, file, search_strings)
                    # 获取key对应的value
                    # value = r.get(key)
                    # if value:  # 确保value不是None
                    #     # 检查value是否包含任何一个search_strings中的字符串
                    #     for search_string in search_strings:
                    #         if search_string in value:
                    #             print(f"Key: {key}, Value: {value}, contains: {search_string}")
                    #             break  # 如果已经找到一个匹配的字符串,可以跳出内层循环
                except Exception as e:
                    print(f"Error scanning keys, error: {e}")
            # 注意:上面的代码假设所有value都是字符串。如果value是其他类型(如列表、集合等),则需要相应地调整检查逻辑。

在Python的redis库或类似的Redis客户端库中,decode_responses=True是一个非常重要的参数,它决定了从Redis服务器接收到的响应数据是如何被处理的。

解释

默认情况下,当你从Redis数据库读取数据时(比如使用gethgetlrange等命令),返回的数据类型是bytes(字节串)。这是因为Redis本身是以二进制安全的方式存储数据的,所以它返回的数据也是原始的二进制数据。

当你设置decode_responses=True时,客户端库会自动将接收到的bytes类型数据解码为字符串(str)。这通常意味着,如果你的数据原本是以UTF-8或其他编码方式存储的文本,那么你就可以直接以字符串的形式处理这些数据,而无需手动进行解码。

使用场景

  • 文本数据处理:如果你的Redis数据库主要用于存储和检索文本数据(如字符串、列表中的字符串元素等),那么设置decode_responses=True可以大大简化数据处理流程。
  • 二进制数据处理:如果你需要处理的是二进制数据(如图片、视频文件等),那么你可能不希望自动解码响应。在这种情况下,你应该保持默认设置(即不设置decode_responses或显式设置为False),以便以bytes类型接收数据。

--end---

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值