我想在redis中使用散列中的给定模式访问值,而不提供密钥。
示例
HSET myKey va11 "Hello" val2 "Hi" Val3 "GooMorning" val4 "Good Evening"
HSET myKey2 va11 "one val2 "two" Val3 "three" val4 "four"
我有一组键,其值如上所述。有没有办法在不提供密钥的情况下检索值。
我只是想检查是否有任何与Good *类似的值而没有提供密钥。
答案 0 :(得分:0)
Redis并未提供开箱即用的此功能。但是,如果我正确理解您的问题,您可以轻松添加它。
使用散列中的所有值(例如,在每次散列更新时对ZADD执行),保留一个有序集,例如调用它allvals
。在其上使用ZRANGEBYLEX进行后缀搜索,作为存在检查的手段:
ZRANGEBYLEX allvals "[Good" "[Good\xff"
编辑:鉴于您的澄清,这种方法并非您所寻求的。以下是我对修订过的挑战的看法。
因此。您正在寻找的是一种获取哈希键名称的方法,如果它们在其中一个字段中包含特定值。一种方法是扫描所有哈希值并查找该值(如@tobiash建议的那样),但是,根据数据集的大小,这可能非常昂贵。另一种方法是使用集合作为索引哈希值的方法。基本前提是获取哈希值中的每个值并为其创建集合。每个这样的集合成员都是包含该值的哈希的实际键名。
让我们看看您的示例myKey
应该如何编入索引(是的,我们在这里建立索引)。首先,您将创建以下集合:
SADD idx:Hello myKey
SADD idx:Hi myKey
SADD idx:GooMorning myKey
SADD "idx:Good Evening" myKey
现在,通过idx:Hello
上的SMEMBERS,您将获得所有以Hello
作为值的关键名称。但是,由于您正在寻找的是进行后缀搜索,因此对于每个值,您实际上需要维护多个集合,其中每个集合都索引该值的子字符串。例如,对于字符串Hello
,您实际上需要:
SADD idx:H myKey
SADD idx:He myKey
SADD idx:Hel myKey
SADD idx:Hell myKey
SADD idx:Hello myKey
如果你要创建一个你打电话来更新哈希的脚本,Lua可以在这里提供帮助。应该为脚本提供哈希键名称和字段名称+值。一旦被调用,脚本不仅需要创建/更新实际的散列,还需要迭代所有字段值并为它们构建索引(及其各自的子串)。
如果您需要帮助编写该脚本,请告诉我们;)
答案 1 :(得分:0)
我看到你正在使用" lua" tag - 如果LUA不是必须的,请使用HVALS考虑以下示例。我提供了一些redis-py代码:
import redis
# connect to local redis-server:6379
r = redis.Redis()
# initialize sample "myKey" hash
r.hmset("myKey", {'val1': "Hello", 'val2': "Hi", 'val3': "GoodMorning", 'val4': "Good Evening"})
# provide "starts with" pattern (this could obviously be a regex as well)
pattern = "Good"
# find all values starting with the pattern and return them
values_matching = filter(lambda x: x.startswith(pattern), r.hvals("myKey"))
# print values: ["GoodMorning", "Good Evening"]
print values_matching
您不会说您需要匹配值的键。如果这样做,那么你应该查看HGETALL命令。
阅读您的评论后,编辑:是的,您需要使用HGETALL循环哈希中的所有键/值。修改后的示例如下:
import redis
r = redis.Redis()
r.hmset("myKey", {'val1': "Hello", 'val2': "Hi", 'val3': "GoodMorning", 'val4': "Good Evening"})
pattern = "Good"
# use hgetall() to iterate over all key-value pairs and form values_matching by looking only at pairs where the value starts with "Good"
values_matching = dict([(k, v) for k, v in r.hgetall("myKey").iteritems() if v.startswith(pattern)])
# print values: {'val3': 'GoodMorning', 'val4': 'Good Evening'}
print values_matching