Redis Stack中基于JSON路径属性实现去重的方法咨询
移除Redis Stack中path重复的JSON键
1. 识别重复的path及对应键
首先用聚合查询找出所有重复的path值,以及每个path的重复次数:
FT.AGGREGATE 你的索引名 "*" GROUPBY 1 @$.path REDUCE COUNT 0 AS count FILTER "@count > 1"
替换你的索引名为实际创建的Redis Search索引名称,@$.path对应JSON文档中存储路径的属性路径(如果你的path属性在JSON里是其他路径,比如$.metadata.path,要对应修改)。
查询结果会列出所有重复的path和它们的出现次数,接下来针对每个重复path,获取对应的所有键:
FT.SEARCH 你的索引名 "@$.path:要处理的路径" RETURN 0
RETURN 0表示只返回键名,不返回JSON内容,方便后续处理。
2. 批量删除重复键(保留一个)
手动逐个删除效率低,推荐用Lua脚本批量处理,保证原子性:
local index_name = ARGV[1] local target_path = ARGV[2] -- 检索该path对应的所有键 local search_result = redis.call('FT.SEARCH', index_name, '@$.path:"' .. target_path .. '"', 'RETURN', 0) local total_keys = search_result[1] if total_keys <= 1 then return "无重复键:" .. target_path end -- 保留第一个键,收集其余待删除的键 local keep_key = search_result[2] local del_keys = {} for i = 3, #search_result do table.insert(del_keys, search_result[i]) end -- 执行删除 redis.call('DEL', unpack(del_keys)) return "已删除 " .. #del_keys .. " 个重复键,保留键:" .. keep_key
执行脚本的命令:
EVAL "上面的Lua脚本内容" 0 你的索引名 "/root/fred/subfolder1/subfolder2/subfolder3/"
注意替换脚本中的占位符为实际值。
3. 防止后续重复的建议
为避免再出现重复,存入JSON前先校验是否已有相同path的键:
- 先执行FT.SEARCH查询目标path是否存在
- 如果存在,用
JSON.SET更新已有键的内容 - 如果不存在,再生成新键存入(比如用UUID生成唯一键名)
示例逻辑(可封装成Lua脚本):
local index_name = ARGV[1] local new_path = ARGV[2] local new_json = ARGV[3] -- 检查是否已有该path的键 local exists = redis.call('FT.SEARCH', index_name, '@$.path:"' .. new_path .. '"', 'RETURN', 0, 'LIMIT', 0, 1) if exists[1] > 0 then -- 更新已有键 redis.call('JSON.SET', exists[2], '$', new_json) return "更新已有键:" .. exists[2] else -- 生成新键并存入 local new_key = 'dir:' .. redis.call('UUID') redis.call('JSON.SET', new_key, '$', new_json) return "新增键:" .. new_key end
内容的提问来源于stack exchange,提问作者harrypottar
相关产品推荐
相关产品推荐

