database - 在 Redis 中搜索与给定模式不匹配的键

标签 database search data-structures redis

目标是设计一个队列,其中包含一些值,例如 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 然后遍历每个元素,在 上拆分: 直到我找到一个元素,其中 bc 都不等于 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/

相关文章:

android - 手机联系人android中的搜索算法

algorithm - 树搜索算法(从边缘/队列中删除前面的节点-目标测试-扩展)

Java:通过引用传递/ListIterator.add()

python - 在 Bunch 类型对象中设置和获取属性

mysql - 组合两个 mysql Select 语句,以便我可以对结果数据进行排序

PHP PDO 检查数据是否存在无法正常工作

search - 在 Elastic Search 中模拟字段折叠/按字段分组

java - 需要有关具有到期时间限制的 hashMap 的帮助

database - 系统设计: whether to normalize the departments or not

php - 组织这个 MySQL 数据库的正确方法是什么?