使用Redis的FT.AGGREGATE聚合时如何解析ISO 8601时间?
Redis RediSearch解析ISO 8601时间为时间戳失败的解决方法
问题场景
你的Redis数据库中,键名以data:为前缀的JSON数据包含UTC时区的ISO 8601格式时间字段,示例如下:
(data:key1) { "time": "2023-12-10T10:42:50.277Z" } (data:key2) { "time": "2023-12-15T19:02:40.308Z" }
你尝试用RediSearch的FT.AGGREGATE命令结合parsetime函数将时间字符串转为时间戳,以便统计指定时间范围内的键数量,但执行后得到的numericTime值为null,无法完成转换。
错误原因
你使用的格式字符串存在两个核心问题:
- 年份格式符不匹配:用了
%G(ISO周年份格式符),而你的时间字符串是普通公历年份,应使用%Y。 - 毫秒格式符错误:
%f并非RediSearchparsetime支持的格式符,正确的毫秒格式符是%L。
正确解决方法
方法1:修正parsetime格式字符串
执行以下聚合命令,使用匹配的格式符解析时间字符串:
FT.AGGREGATE mySearch "*" APPLY "parsetime(@time, '%Y-%m-%dT%H:%M:%S.%LZ')" AS numericTime
如果你的时间字符串是标准ISO 8601 UTC格式(带Z后缀),可省略格式参数,parsetime会自动识别:
FT.AGGREGATE mySearch "*" APPLY "parsetime(@time)" AS numericTime
方法2:将时间字段索引为DATE类型(更高效)
创建索引时直接将$.time指定为DATE类型,无需手动转换即可直接做时间范围过滤:
FT.CREATE mySearch ON JSON PREFIX 1 data: SCHEMA $.time AS time DATE
之后直接执行聚合统计指定时间范围的键数量:
FT.AGGREGATE mySearch "@time:[2023-12-10T00:00:00Z TO 2023-12-29T23:59:59Z]" GROUPBY 0 REDUCE COUNT 0 AS total
方法3:基于时间戳的范围过滤(结合方法1)
若需转换为时间戳后统计,可搭配FILTER子句实现:
FT.AGGREGATE mySearch "*" APPLY "parsetime(@time)" AS numericTime FILTER "@numericTime >= 1702166400 AND @numericTime <= 1703894399" GROUPBY 0 REDUCE COUNT 0 AS total
其中1702166400是2023-12-10 00:00:00 UTC的时间戳,1703894399是2023-12-29 23:59:59 UTC的时间戳。
内容的提问来源于stack exchange,提问作者goose_lake
相关产品推荐
相关产品推荐

