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

OPA Rego中如何基于多属性排序对象集合并返回对应id

OPA Rego 多属性排序返回对象ID实现方案

需求说明

  • 输入为键是对象ID、值是对象属性的字典结构,测试数据如下:
dict = { 
    "1": {"name": "ccc", "foo": "4"},
    "2": {"name": "aaa", "foo": "1"},
    "3": {"name": "bbb", "foo": "6"},
    "4": {"name": "eee", "foo": "5"},
    "5": {"name": "eee", "foo": "2"},
    "6": {"name": "ddd", "foo": "3"} 
}
  • 排序规则:优先按name属性升序排序,name值相同时按foo属性升序排序
  • 预期输出:按排序规则排列的对象ID列表 ["2","3","1","6","5","4"],其中ID为4、5的对象name值均为eee,需按foo值升序排列,即foo=2的ID5排在foo=5的ID4前。

历史实现的问题

第一次实现

_sorted = res{ 
    orderBy = ["name", "foo"]
    sorted1 = sort([ x | x := dict[_][orderBy[0]] ])
    res = [id | sorted1[_] == dict[id][orderBy[0]] ]
}

问题:仅对第一排序字段name的取值列表做排序,未对同name值的对象做区分。当多个对象name值相同时,遍历匹配ID会重复匹配所有同name值的对象,最终返回结果出现重复ID,错误输出为["2","3","1","6","4","5","4","5"]。

第二次实现

_sorted = res{ 
    orderBy = ["name", "foo"]
    sorted1 = { x | x := dict[_][orderBy[0]] }
    res = [id | sorted1[_] == dict[id][orderBy[0]] ]
}

问题:用集合存储第一排序字段的取值,虽然避免了ID重复,但集合本身无序,且完全没有实现第二排序字段的逻辑,无法满足多属性排序要求。

第三次实现

_sorted = res{ 
    orderBy = ["name", "foo"]
    sorted1 = { x | x := dict[_][orderBy[0]] }
    sorted2 = { x | x := dict[_][orderBy[1]] }
    res = [id | sorted1[_] == dict[id][orderBy[0]]; sorted2[_] == dict[sid][orderBy[1]] ]
}

问题:两个排序字段的取值集合完全独立,未建立字段值和对应ID的关联关系,且代码中存在未定义的sid变量,无法输出正确结果。

可行实现方案

Rego原生sort函数支持对复合结构数组逐位比较排序,核心思路是将每个对象的排序键按优先级顺序+对象ID组装为数组,整体排序后提取末尾的ID即可,天然支持多字段优先级排序。
实现代码如下:

_sorted = res {
    orderBy := ["name", "foo"]
    # 组装结构为 [第一排序键值, 第二排序键值, ..., 对象ID] 的数组
    items := [ [x[orderBy[i]] | i := range(array.count(orderBy))] + [id] | 
        id := object.keys(dict)[_]
        x := dict[id]
    ]
    # 复合数组排序:Rego会按数组元素顺序逐位比较,自动适配多字段优先级
    sorted_items := sort(items)
    # 提取排序后每个条目的最后一位(即对象ID)得到最终结果
    res := [ item[array.count(orderBy)] | item := sorted_items[_] ]
}

方案说明

  • 排序逻辑完全符合要求:比较时先匹配第一位name值,name值相同则自动比较第二位foo值,针对测试数据运行后返回结果为["2","3","1","6","5","4"],和预期完全一致
  • 扩展性强:需要增加排序字段时,仅需按优先级顺序在orderBy数组中追加字段名即可,无需修改核心排序逻辑
  • 无重复ID、无无序问题:每个组装条目绑定唯一ID,数组结构保留排序顺序,不会出现之前实现的各类异常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 11:45:37