我正在尝试存储媒体对象,并让它们可以通过 redis 在特定时间范围内检索。我选择了一个排序集数据类型来执行此操作。我正在添加如下元素:
zAdd: key: media:552672 score: 1355264694
zAdd: key: media:552672 score: 1355248565
zAdd: key: media:552672 score: 1355209157
zAdd: key: media:552672 score: 1355208992
zAdd: key: media:552672 score: 1355208888
zAdd: key: media:552672 score: 1355208815
其中,key 是媒体拍摄位置的唯一标识,score 是媒体对象的创建时间。该值是媒体对象的 json_decode。
当我使用zRevRangeByScore 去检索时,偶尔会出现重复条目。我本质上是将 Redis 用作外部 API 的缓冲区,如果用户在 X 秒内两次调用相同的 API,那么我将从缓存中检索结果,否则,我会将其添加到缓存中,而不是检查查看它是否由于不包含重复项的集合的定义而已经存在。
可能的已知问题:
如果媒体对象属性在缓存之间发生变化,它将显示为重复项
有没有更好的方法来存储这种类型的数据,而无需在 redis 客户端进行检查?
TLDR; 在 Redis 中存储和检索对象的最佳方式是什么,您可以通过时间戳选择一系列对象并确保它们是唯一的?
最佳答案
让我们确保我们在谈论相同的事情,所以这里是 Redis 排序集的术语:
ZADD key score member [score] [member]
summary: Add one or more members to a sorted set, or update its score if it already exists
key - 排序集的“名称”score - 得分(在我们的例子中是时间戳)member - 分数关联的字符串听起来您正在使用对象的 JSON 编码字符串作为成员。成员是有序集合中唯一的。正如您所说,如果对象发生更改,它将作为新成员添加到排序集中。这可能不是您想要的。
有序集是 Redis 按时间戳存储数据的方式,但存储在集合中的成员通常是指向 Redis 中另一个键的“指针”。
根据你的描述,我认为你想要这个数据结构:
我建议将媒体对象存储在哈希中,因为这样可以提供更大的灵 active 。 示例:
# add some members to our sorted set
redis 127.0.0.1:6379> ZADD media 1000 media:1 1003 media:2 1001 media:3
(integer) 3
# create hashes for our members
redis 127.0.0.1:6379> HMSET media:1 id 1 name "media one" content "content string for one"
OK
redis 127.0.0.1:6379> HMSET media:2 id 2 name "media two" content "content string for two"
OK
redis 127.0.0.1:6379> HMSET media:3 id 3 name "media three" content "content string for three"
OK
有两种方法可以检索以这种方式存储的数据。如果您需要获取特定时间戳范围内的成员(例如:过去 7 天),您将必须使用 ZREVRANGEBYSCORE 来检索成员,然后遍历这些以使用 HGETALL 或类似的。参见 pipelining了解如何通过对服务器的一次调用来完成循环。
redis 127.0.0.1:6379> ZREVRANGEBYSCORE media +inf -inf
1) "media:2"
2) "media:3"
3) "media:1"
redis 127.0.0.1:6379> HGETALL media:2
1) "id"
2) "2"
3) "name"
4) "media two"
5) "content"
6) "content string for two"
如果您只想获取最后的 n 个成员(或者例如:最近的第 10 个到最近的第 100 个),您可以使用 SORT 来获取项目。查看sort documentation了解语法以及如何检索不同的哈希字段、限制结果和其他选项。
redis 127.0.0.1:6379> SORT media BY nosort GET # GET *->name GET *->content1) DESC
1) "media:2"
2) "media two"
3) "content string for two"
4) "media:3"
5) "media three"
6) "content string for three"
7) "media:1"
8) "media one"
9) "content string for one"
注意:按分数对已排序的哈希进行排序(BY nosort)仅适用于 Redis 2.6。
如果您计划获取最后一天、一周、一个月等的媒体。我建议为每个媒体使用单独的排序集,并使用 ZREMRANGEBYSCORE 删除旧成员。然后,您可以对这些已排序的集合使用 SORT 来检索数据。
关于redis - 确保redis中排序集的唯一性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13831926/
关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion为什么SecureRandom.uuid创建一个唯一的字符串?SecureRandom.uuid#=>"35cb4e30-54e1-49f9-b5ce-4134799eb2c0"SecureRandom.uuid方法创建的字符串从不重复?
我有一个允许更新用户记录的表单。它包含:password和:password_confirmation字段,但我不希望在数据库中已存储加密密码时对它们运行验证。View文件中的字段:'ConfirmPassword'%>在互联网上搜索时,我发现了这段代码,我认为它是针对以前版本的Ruby/Rails的。(我会把它放在我的用户模型中。)validates_presence_of:password,:on=>create由于我的用户模型中密码验证的语法不同(如下),我对我需要的语法感到困惑。validates:password,:presence=>true,:confirmation=>
我想通过内部数组中的第一个元素从数组数组中找到唯一元素。例如a=[[1,2],[2,3],[1,5]我想要类似的东西[[1,2],[2,3]] 最佳答案 uniq方法需要一个block:uniq_a=a.uniq(&:first)或者如果您想就地进行:a.uniq!(&:first)例如:>>a=[[1,2],[2,3],[1,5]]=>[[1,2],[2,3],[1,5]]>>a.uniq(&:first)=>[[1,2],[2,3]]>>a=>[[1,2],[2,3],[1,5]]或者>>a=[[1,2],[2,3],[1,5]
给定一个包含各种语言字符的UTF-8文件,我如何计算它包含的唯一字符的数量,同时排除选定数量的符号(例如:“!”、“@”、"#",".")从这个算起? 最佳答案 这是一个bash解决方案。:)bash$perl-CSD-ne'BEGIN{$s{$_}++forsplit//,q(!@#.)}$s{$_}++||$c++forsplit//;END{print"$c\n"}'*.utf8 关于python-如何计算文件中唯一字符的数量?,我们在StackOverflow上找到一个类似的问题
如何以最佳方式在字符串中找到唯一元素?示例字符串格式为myString="34345667543"对/对['3','4','3','5'.....] 最佳答案 这是一个有趣的问题,因为它返回了很多几乎相似的结果,所以我做了一个简单的基准测试来决定哪个实际上是最好的解决方案:require'rubygems'require'benchmark'require'set'puts"Dothetest"Benchmark.bm(40)do|x|STRING_TEST="26263636362626218118181111232112233"
我计划将STIinRails与以下模型一起使用:classPromoEvent和Discount在属性方面仅存在一些差异,因此我认为STI是一个不错的选择。我不确定如何确保,例如,仅Event具有额外的image_filename属性。我知道它会在promos表中,并且它必须是NULL-able以防我插入Discount行。如何确保Discount对象对image_filename属性一无所知(即未在Discount.column_names中列出>和/或无法设置它)Event知道它吗? 最佳答案 我认为这个概念是不同的,而你的Pr
link有两个组件:componenta_id和componentb_id。为此,在Link模型文件中我有:belongs_to:componenta,class_name:"Component"belongs_to:componentb,class_name:"Component"validates:componenta_id,presence:truevalidates:componentb_id,presence:truevalidates:componenta_id,uniqueness:{scope::componentb_id}validates:componentb_id
出于某种原因,以下代码产生了一个具有重复值的集合。我不确定ruby中数组的唯一性是如何定义的,所以也许这在某种程度上是可以预料的?require'set'xs=[1,2,3]xss=Set.new[]xs.eachdo|x|xss.mergexss.to_a.map{|xs|xs.pushx}xss.add[x]pxssend将打印###怎么了?编辑将xs.pushx更改为xs+[x]将修复它。 最佳答案 您实际上是在更改集合中的对象,这是不允许的。来自documentation:Setassumesthattheidentit
我有一个操作需要在我的Rails应用程序终止之前在我的Rails应用程序中执行。我可以在Rails中为此使用一个钩子(Hook)吗?我猜类似于at_exit的东西。 最佳答案 Ruby本身支持两个钩子(Hook),BEGIN和END,它们在脚本开始时运行,并在解释器停止运行时运行。有关详细信息,请参阅“WhatdoesRuby'sBEGINdo?”。BEGIN文档说:Designates,viacodeblock,codetobeexecutedunconditionallybeforesequentialexecutionofth
我想从rubocop中排除一个全局变量,但我找不到规则名称。我尝试添加GlobalVars:Exclude:-redis到.rubocop.yml但运气不好。错误说不要引入全局变量。 最佳答案 使用AllowedVariables切换Exclude. 关于ruby-如何从rubocop中排除全局变量?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/44004319/