Redis - 排序集,按属性值查找项目 [英] Redis - Sorted set, find item by property value

查看:36
本文介绍了Redis - 排序集,按属性值查找项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In redis I store objects in a sorted set. In my solution, it's important to be able to run a ranged query by dates, so I store the items with the score being the timestamp of each items, for example:

#   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"}

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

However, in other situations I need to find a single item in the set based on it's ID. I know I can't just query this data structure as if it were a nosql db, but I tried using ZSCAN, which didn't work.

ZSCAN MySet 0 MATCH Id:92 count 1

它回来了;空列表或集合"

It returns; "empty list or set"

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

Maybe I need to serialize different? I have serialized using Json.Net.

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

How, if possible, can I achieve this; using dates as score and still be able to lookup an item by it's ID?

非常感谢,

拉斯

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

Assume it's not possible, but any thoughts or inputs are welcome:

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

在Redis中,数据只能通过key来查询.即使我们使用哈希,我们不能说在任何场地比赛等于的地方给我钥匙萨扬.

In Redis, data can only be queried by its key. Even if we use a hash, we can't say get me the keys wherever the field race is equal to 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"

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

And it finds the desired item, but it also finds another one with an occurance of 87 in the property ATime. Having more unique, longer IDs might work this way and I would have to filter the results in code to find the one with the exact value in its property.

仍然开放接受建议.

推荐答案

我觉得很简单.

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

Your way of ZSCAN MySet 0 MATCH Id:92 count 1 didn't work out because the stored string is "{\"Id\":\"92\"... not "{\"Id:92\".... The string has been changed into another format. So try to use MATCH Id\":\"64 or something like that to match the json serialized data in redis. I'm not familiar with json.net, so the actual string leaves for you to discover.

顺便问一下,ZSCAN MySet 0 MATCH Id:92 count 1 返回游标了吗?我怀疑您以错误的方式使用了 ZSCAN.

By the way, I have to ask you did ZSCAN MySet 0 MATCH Id:92 count 1 return a cursor? I suspect you used ZSCAN in a wrong way.

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

ZSCAN is good when your sorted set is not large and you know how to save network roundtrip time by Redis' Lua transaction. This still make "look up by ID" operation O(n). Therefore, a better solution is to change you data model in the following way:

改变排序集来自

#   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"}

#   Score   Value
0   1443476076 Id:92
1   1443482969 Id:11

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

Move the rest detailed data in another set of hashes type keys:

#   Key   field-value field-value ...
0   Id:92 Ref-7ADT DTime-1443476076 ...
1   Id:11 Ref-7ADT DTime-1443476076 ...

然后,您可以通过执行 hgetall id:92 通过 id 进行定位.对于按日期进行范围查询,您需要对每个 id 进行 ZRANGEBYSCORE sortedset mindate maxdate 然后 hgetall 每个 id.你最好用lua把这些命令打包成一个,还是超级快的!

Then, you locate by id by doing hgetall id:92. As to ranged query by date, you need do ZRANGEBYSCORE sortedset mindate maxdate then hgetall every id one by one. You'd better use lua to wrap these commands in one and it will still be super fast!

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

Data in NoSql database need to be organized in a redundant way like above. This may make some usual operation involve more than one commands and roundtrip, but it can be tackled by redis's lua feature. I strongly recommend the lua feature of redis, cause it wrap commands into one network roundtrip, which are all executed on the redis-server side and is atomic and super fast!

有不懂的请回复

这篇关于Redis - 排序集,按属性值查找项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆