我有一个数据库,其中的key以ISO 8601格式存储UTC时间,如下所示:
(data:key1)
{ "time": "2023-12-10T10:42:50.277Z" }
(data:key2)
{ "time": "2023-12-15T19:02:40.308Z" }
...
字符串
我想以某种方式聚合这些键中的数据,比方说我想计算时间在2023-12-10和2023-12-29之间的键的数量。
Redis在其RediSearch模块中包含了FT.AGGREGATE
命令,以及一个APPLY
子命令,该子命令可用于使用不同类型的表达式转换数据。要将基于字符串的时间转换为数值,文档中列出的两个转换似乎不错:
**timefmt(x, [fmt])
根据数字时间戳值x返回格式化的时间字符串。有关格式化选项,请参阅strftime。不指定fmt相当于%FT%TZ。parsetime(timesharing, [fmt])
**与timefmt()相反-使用给定的格式字符串解析时间格式
然而,我找不到一种方法来实现这一点。我首先用FT.CREATE mySearch ON JSON PREFIX 1 data: SCHEMA $.time AS time TEXT
创建一个搜索索引,然后调用FT.AGGREGATE mySearch "*" APPLY "parsetime(@time, '%G-%m-%dT%H:%M:%S.%fZ')" as numericTime
进行聚合,响应是:
1) "1"
2) 1) "time"
2) "2023-12-14T20:42:50.277Z"
3) "numericTime"
4) "null" // <- this should be a unix timestamp instead of null
型
我做错了什么,以及将这些时间字符串解析为数值的正确方法是什么?
1条答案
按热度按时间axkjgtzd1#
我花了20分钟来观察Redis如何响应包含日期和时间的各种字符串。
null
,如果你给予它的格式选项是无效的。我尝试了它与%q
,这是非常无效的,以确认这一点。%f
的微秒格式,而Python格式规范支持。事实上,它根本不支持秒的分数。所以,这是行不通的。在我看来,你有两个选择:
*如果毫秒很重要,你可以在将其保存到Redis之前将其转换为UNIX Epoch时间。搜索将很乐意处理包含小数的数字。亲自完成。完全有效。只要确保将其保存为JSON中的 number,而不是包含数字的字符串。
*如果毫秒不重要,在保存到Redis之前,请从ISO 8601日期中删除毫秒。
还有几件事值得注意:
%G
表示年份。它应该是%Y
。%G
是基于周的年份,而不是实际年份。ISO 8601日期使用实际年份。%F
是%Y-%m-%d
的缩写,%T
是%H:%M:%S
的缩写。%Z
来匹配时区。这比使用硬编码的Z
更健壮一些,因为您可能会遇到指定时区的时间。所有这一切都表明,我可以修改你的解析字符串为
%FT%T%Z
,但我认为%Y-%m-%dT%H:%M:%S%Z
可能更容易阅读。无论如何,这是一个很长的回答,但我希望它能有所帮助!