目标是设计一个队列,其中包含一些值,例如 A。但只有当传入值 D 与 B 和 C 不匹配时,我才必须从队列中选择一个值。
A、B、C 之间的关系可以看作是表格数据。
+------------------+------------------+------------------+
| A | B | C |
+------------------+------------------+------------------+
| 12312 | 123123 | 2323 |
| <some int value> | <some int value> | <some int value> |
+------------------+------------------+------------------+
我有一个传入值D。
现在我必须简单地从 D 的值不等于 B 或 C 的行中选择值 A。
请注意 A、B、C 都不是事先知道的。这些将由 db 或 redis 中的单独进程填充。我知道的唯一值是 D,我必须在第一行找到 A 的值,我发现值 B 和 C 与 D 不匹配。
如果我在关系数据库上执行此操作,这将非常简单,即示例查询将是
Select A from table where B != D and C != D LIMIT 1
但我不确定如何使用像 Redis 这样的键值存储来做到这一点?
尝试 1
最基本的想法是按照以下格式在redis中维护一个列表
somekey: ['a1:b1:c1', 'a2:b2:c2', 'a3:b3:c3', ...]
然后我可以简单地运行 lrange somekey 0 -1
然后遍历每个元素,在 上拆分:
直到我找到一个元素,其中 b
和 c
都不等于 D
。
但是这种方法非常昂贵,因为我必须为 D 的每个值遍历整个列表。
尝试2
另一种方法我尝试以下列格式创建 redis 键
+------------------+-----------------------------+
| Key | Value |
+------------------+-----------------------------+
| prefix_<B1>_<C1> | [<A11>, <A12>, <A13>, ....] |
| prefix_<B2>_<C2> | [<A21>, <A22>, <A23>, ....] |
+------------------+-----------------------------+
这种方法的问题在于,redis 不支持搜索不匹配模式
的键。
所以我必须先获取所有 key ,然后在应用程序级别进行正则表达式搜索。
然后一旦我找到一个键,我就从该键处的列表中弹出第一个值。
我的首选方法是使用 Redis,但也欢迎使用其他解决方案。
最佳答案
假设您以下列格式存储值:
+--------------+-----------------+
| key | value |
+--------------+-----------------+
| a1:b1:c1 | any value |
+--------------+-----------------+
| a2:b2:c2 | any value |
+--------------+-----------------+
| a3:b3:c3 | any value |
+--------------+-----------------+
| a4:b4:c4 | any value |
+--------------+-----------------+
对于任何值 d
,您需要所有不包含 d:d 作为后缀的键,例如 whatever:d:d
,这是以下正则表达式返回后缀中不包含 d:d
的所有键。
KEYS *[^d:d]
假设 d
的值为 123
那么模式将为:*[^123:123]
。
以下是我在控制台中测试过的一些情况:
127.0.0.1:6379> set 123:456:789 one
OK
127.0.0.1:6379> set 123:456:780 two
OK
127.0.0.1:6379> set 123:456:787 two
OK
127.0.0.1:6379> set 123:455:787 two
OK
127.0.0.1:6379> set aaa:bbb:ccc abc
OK
127.0.0.1:6379> set aaa:ddd:ddd abc
OK
127.0.0.1:6379> keys *
1) "123:456:789"
2) "123:456:787"
3) "123:455:787"
4) "aaa:ddd:ddd"
5) "aaa:bbb:ccc"
6) "123:456:780"
127.0.0.1:6379> keys aaa:*[^ddd:ddd]
1) "aaa:bbb:ccc"
127.0.0.1:6379> keys *[^ddd:ddd]
1) "123:456:789"
2) "123:456:787"
3) "123:455:787"
4) "aaa:bbb:ccc"
5) "123:456:780"
查看命令 keys *[^ddd:ddd]
返回所有与我们预期的 key 不匹配的 key 。
1) "123:456:789"
2) "123:456:787"
3) "123:455:787"
4) "aaa:bbb:ccc"
5) "123:456:780"
更多信息请查看此链接:REDIS KEYS
您还可以使用 REDIS SCAN 命令来获取不匹配的键:
scan 0 MATCH *[^d:d] count 1000
关于database - 在 Redis 中搜索与给定模式不匹配的键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57285507/