You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RediSearch索引JSON数组时,能否返回匹配数组项的指定属性?

RedisJSON搜索数组对象属性并返回匹配项指定字段

问题场景

我在Redis中存储了多组JSON类型的实体,键名格式如userlist:1、userlist:2,键值结构示例如下:

{
  "name": "accounting_team",
  "people": [
    {
      "name": "Ahmed",
      "email": "ahmed@some.domain"
    },
    {
      "name": "Boris",
      "email": "boris@some.domain"
    }
  ]
}

需求是:通过数组对象的属性(如email)搜索,返回两个结果:

  • 匹配的Redis键名(如userlist:1)
  • 匹配对象的指定属性(如对应目标email的name值)

当前实现与问题

已创建索引实现邮箱属性的搜索:

FT.CREATE nameSearch ON JSON PREFIX 1 userlist: SCHEMA $.people.*.email AS userEmail TAG

执行搜索命令能返回对应的键和完整JSON内容:

FT.SEARCH nameSearch '@userEmail:{boris\@some\.domain}'

但使用RETURN指定路径时,返回的是数组第一个元素的属性而非匹配项:

FT.SEARCH nameSearch '@userEmail:{boris\@some\.domain}' RETURN 1 $.people.*.email
# 返回结果为Ahmed的邮箱,而非Boris的

解决方案

方法1:带条件过滤的JSONPath直接返回匹配属性

在FT.SEARCH的RETURN参数中,使用RedisJSON支持的条件JSONPath,精准定位匹配的对象属性:

FT.SEARCH nameSearch '@userEmail:{boris\@some\.domain}' RETURN 2 '__key' '$.people[?(@.email == "boris@some.domain")].name'
  • __key:直接返回匹配的Redis键名
  • $.people[?(@.email == "boris@some.domain")].name:通过JSONPath过滤表达式,提取与目标邮箱匹配的对象的name属性

注意:需将搜索的邮箱值同步代入JSONPath的过滤条件中,保证匹配一致性。

方法2:FT.AGGREGATE展开数组并过滤

通过FT.AGGREGATE的UNWIND指令展开数组元素,再筛选匹配项,最后返回目标字段,适合复杂数组处理场景:

FT.AGGREGATE nameSearch '@userEmail:{boris\@some\.domain}' \
  LOAD 2 '@__key' '$.people' \
  UNWIND '$people' AS person \
  FILTER '@person.email == "boris@some.domain"' \
  RETURN 2 '@__key' '@person.name'

步骤说明:

  1. LOAD:加载匹配键的键名和整个people数组
  2. UNWIND:将数组展开为单个元素(每个元素对应一行聚合结果)
  3. FILTER:筛选出邮箱匹配的数组元素
  4. RETURN:输出键名和匹配元素的name属性

补充说明

  • 方法1适合简单单次查询,写法简洁,但需硬编码匹配值到JSONPath中
  • 方法2更灵活,支持批量处理和动态参数场景,无需在路径中硬编码匹配值

内容的提问来源于stack exchange,提问作者goose_lake

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 16:16:29