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

如何在JSON Schema中实现数值属性的最小/最大值依赖于其他属性?

关于JSON Schema动态依赖属性范围约束的解决方案

你猜的没错,标准JSON Schema(包括最新的Draft 2020-12)确实没办法直接写出你想要的这种动态范围约束——minimum和maximum这类关键字只能接受固定数值,没办法引用实例中其他属性的值来做实时计算。你提到的if-then-else功能只能基于属性的固定值或静态范围触发分支,无法处理“基于另一个属性的动态计算结果”这类场景。

不过根据你的需求,还是有几种可行的替代方案:

方案1:针对离散值使用allOf+if-then(纯标准Schema)

如果foo的可能取值是有限的离散值(比如你这里是10-20的整数,共11个可选值),可以通过allOf配合多个if-then块逐个覆盖每个foo值对应的bar范围:

{
  "type": "object",
  "properties": {
    "foo": {
      "type": "integer",
      "minimum": 10,
      "maximum": 20
    },
    "bar": {
      "type": "integer"
    }
  },
  "allOf": [
    {
      "if": { "properties": { "foo": { "const": 10 } } },
      "then": { "properties": { "bar": { "minimum": 6, "maximum": 8 } } }
    },
    {
      "if": { "properties": { "foo": { "const": 15 } } },
      "then": { "properties": { "bar": { "minimum": 9, "maximum": 12 } } }
    },
    {
      "if": { "properties": { "foo": { "const": 20 } } },
      "then": { "properties": { "bar": { "minimum": 12, "maximum": 16 } } }
    }
    // 继续为foo的其他取值(11-14、16-19)添加对应的if-then约束
  ]
}

注意:这种方式的局限性很明显——如果foo的取值范围很大(比如0-1000的整数)或者是浮点数,写起来会非常繁琐,几乎不现实。

方案2:借助验证器扩展实现自定义逻辑

如果可以灵活选择JSON Schema验证器(比如主流的Ajv),你可以通过自定义关键字来实现动态范围计算,这样就能在Schema里统一管理所有约束。

以Ajv为例,你可以注册一个自定义关键字(比如rangeDependsOn),然后编写验证逻辑来计算bar的动态范围:

1. 定义带自定义关键字的Schema

{
  "type": "object",
  "properties": {
    "foo": {
      "type": "integer",
      "minimum": 10,
      "maximum": 20
    },
    "bar": {
      "type": "integer",
      "rangeDependsOn": {
        "property": "foo",
        "minMultiplier": 0.6,
        "maxMultiplier": 0.8
      }
    }
  }
}

2. 在Ajv中注册自定义关键字的验证逻辑

const Ajv = require('ajv');
const ajv = new Ajv();

ajv.addKeyword('rangeDependsOn', {
  validate: (schema, barValue, _, __, parentData) => {
    const fooValue = parentData.foo;
    // 如果foo不合法,基础Schema校验会先报错,这里直接返回true即可
    if (typeof fooValue !== 'number') return true;
    
    // 根据需求调整取整逻辑(比如向下取整、向上取整或四舍五入)
    const min = Math.floor(fooValue * schema.minMultiplier);
    const max = Math.floor(fooValue * schema.maxMultiplier);
    
    return barValue >= min && barValue <= max;
  },
  schemaType: 'object'
});

// 编译Schema并验证实例
const validate = ajv.compile(yourSchema);
const isValid = validate(yourConfig);

总结

  • 如果必须严格遵循标准JSON Schema,且foo的取值是有限离散值,方案1可以满足需求;否则只能通过外部逻辑完成动态范围校验。
  • 如果可以使用支持扩展的验证器,方案2是最优雅的解决方式,能把所有约束统一在Schema中管理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 16:19:07