Redis - 排序集,按属性值查找项目

Lar*_*kås 4 redis

在 redis 中,我将对象存储在一个有序集合中。在我的解决方案中,能够按日期运行范围查询很重要,因此我将分数存储为每个项目的时间戳的项目,例如:

#   Score   Value
0   1443476076  {"Id":"92","Ref":"7ADT","DTime":1443476076,"ATime":1443901554,"ExTime":0,"SPName":"7ADT33CFSAU6","StPName":"7ADT33CFSAU6"}
1   1443482969  {"Id":"11","Ref":"DAJT","DTime":1443482969,"ATime":1443901326,"ExTime":0,"SPName":"DAJTJTT4T02O","StPName":"DAJTJTT4T02O"}
Run Code Online (Sandbox Code Playgroud)

但是,在其他情况下,我需要根据它的 ID 在集合中找到单个项目。我知道我不能只查询这个数据结构,就好像它是一个 nosql db,但我尝试使用ZSCAN,但没有用。

ZSCAN MySet 0 MATCH Id:92 count 1
Run Code Online (Sandbox Code Playgroud)

它回来了;“空列表或集合”

也许我需要序列化不同的?我已经使用 Json.Net 进行了序列化。

如果可能的话,我怎样才能做到这一点;使用日期作为分数并且仍然能够通过它的 ID 查找一个项目?

非常感谢,

拉斯

编辑:

假设这是不可能的,但欢迎提出任何想法或意见:

参考:http : //openmymind.net/2011/11/8/Redis-Zero-To-Master-In-30-Minutes-Part-1/

在Redis中,数据只能通过key来查询。即使我们使用散列,我们也不能说在字段竞赛等于 sayan 的任何地方给我获取密钥。

编辑2:

我试图做:

ZSCAN MySet 0 MATCH *87*

127.0.0.1:6379> ZSCAN MySet 0 MATCH *87*
1) "192"
2) 1) "{\"Id\":\"64\",\"Ref\":\"XQH4\",\"DTime\":1443837798,\"ATime\":1444187707,\"ExTime\":0,\"SPName\":\"XQH4BPGW47FM\",\"StPName\":\"XQH4BPGW47FM\"}"
   2) "1443837798"
   3) "{\"Id\":\"87\",\"Ref\":\"5CY6\",\"DTime\":1443519199,\"ATime\":1444172326,\"ExTime\":0,\"SPName\":\"5CY6DHP23RXB\",\"StPName\":\"5CY6DHP23RXB\"}"
   4) "1443519199"
Run Code Online (Sandbox Code Playgroud)

它会找到所需的项目,但还会在属性 ATime 中找到另一个出现次数为 87 的项目。拥有更多唯一、更长的 ID 可能会以这种方式工作,我将不得不在代码中过滤结果以在其属性中找到具有确切值的结果。

仍然开放的建议。

Mur*_* Ng 6

我认为这很简单。

方案一(较差,不推荐)

你的方式ZSCAN MySet 0 MATCH Id:92 count 1没有成功,因为存储的字符串"{\"Id\":\"92\"...不是"{\"Id:92\".... 字符串已更改为另一种格式。所以尝试使用MATCH Id\":\"64或类似的东西来匹配redis中的json序列化数据。我对 json.net 不熟悉,所以实际的字符串留给你去发现。

顺便问一下,你有没有ZSCAN MySet 0 MATCH Id:92 count 1返回一个游标?我怀疑你用ZSCAN错了方法。

解决方案2(更好,强烈推荐)

ZSCAN当您的排序集不大并且您知道如何通过 Redis 的 Lua 事务节省网络往返时间时,这很好。这仍然使“按 ID 查找”操作 O(n)。因此,更好的解决方案是通过以下方式更改数据模型:

改变排序集

#   Score   Value
0   1443476076 {"Id":"92","Ref":"7ADT","DTime":1443476076,"ATime":1443901554,"ExTime":0,"SPName":"7ADT33CFSAU6","StPName":"7ADT33CFSAU6"}
1   1443482969 {"Id":"11","Ref":"DAJT","DTime":1443482969,"ATime":1443901326,"ExTime":0,"SPName":"DAJTJTT4T02O","StPName":"DAJTJTT4T02O"}
Run Code Online (Sandbox Code Playgroud)

#   Score   Value
0   1443476076 Id:92
1   1443482969 Id:11
Run Code Online (Sandbox Code Playgroud)

将其余详细数据移动到另一组散列类型键中:

#   Key   field-value field-value ...
0   Id:92 Ref-7ADT DTime-1443476076 ...
1   Id:11 Ref-7ADT DTime-1443476076 ...
Run Code Online (Sandbox Code Playgroud)

然后,您通过执行 id 来定位hgetall id:92。至于按日期范围查询,你需要做的ZRANGEBYSCORE sortedset mindate maxdate,然后hgetall由每一个ID只能有一个。你最好使用 lua 将这些命令合二为一,它仍然会超级快!

NoSql 数据库中的数据需要像上面一样以冗余方式组织。这可能会使一些通常的操作涉及多个命令和往返,但可以通过 redis 的 lua 特性来解决。我强烈推荐 redis 的 lua 特性,因为它将命令包装成一个网络往返,这些都在 redis-server 端执行,并且原子性超快!

有不懂的可以回复