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

如何用AJV JSON Schema校验器校验嵌套对象中prop1的唯一性

使用AJV校验嵌套对象中所有子对象的prop1值唯一性

首先要纠正你给出的JSON示例的语法错误——JSON对象必须是键值对结构,不能直接在父对象中放置无键的子对象,正确的结构应该类似这样:

{
  "obj2": {
    "item1": {
      "prop1": "baz",
      "prop2": 999
    },
    "item2": {
      "prop1": "qux",
      "prop2": 555
    }
  }
}

标准JSON Schema的关键字(比如针对数组的uniqueItems)确实不支持直接校验对象值的唯一性,但AJV允许通过自定义关键字实现这个需求,具体步骤如下:

1. 注册自定义校验关键字

初始化AJV实例后,注册一个自定义关键字(比如uniquePropValues),编写逻辑遍历父对象的所有子值,提取指定字段并检查唯一性:

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

// 注册自定义关键字
ajv.addKeyword({
  keyword: 'uniquePropValues',
  type: 'object',
  validate: function(schema, parentObj) {
    // schema参数是关键字的配置值,这里指定要检查的字段名,比如"prop1"
    const propName = schema;
    const propValues = [];

    // 遍历父对象的所有子值
    for (const key in parentObj) {
      const childObj = parentObj[key];
      // 跳过非对象类型的子值(根据需求调整)
      if (typeof childObj !== 'object' || childObj === null) continue;
      // 如果子对象没有目标字段,可选择抛出错误或忽略,这里选择忽略
      if (!(propName in childObj)) continue;

      const value = childObj[propName];
      // 检查值是否重复
      if (propValues.includes(value)) {
        // 校验失败,返回false,可添加错误信息
        this.errors = [{
          keyword: 'uniquePropValues',
          message: `Duplicate value "${value}" for property "${propName}"`,
          params: { propName, duplicateValue: value }
        }];
        return false;
      }
      propValues.push(value);
    }
    return true;
  },
  errors: true // 允许自定义错误信息
});

2. 编写JSON Schema并使用自定义关键字

在Schema中,针对obj2字段使用自定义的uniquePropValues关键字,指定要检查的字段为prop1:

const schema = {
  type: 'object',
  properties: {
    obj2: {
      type: 'object',
      // 自定义关键字,指定要检查唯一的字段名
      uniquePropValues: 'prop1',
      // 可选:先校验子对象的结构
      additionalProperties: {
        type: 'object',
        properties: {
          prop1: { type: 'string' },
          prop2: { type: 'integer' }
        },
        required: ['prop1', 'prop2']
      }
    }
  },
  required: ['obj2']
};

3. 校验数据

使用AJV实例编译Schema并校验数据:

const validate = ajv.compile(schema);

// 校验通过的示例数据
const validData = {
  "obj2": {
    "item1": { "prop1": "baz", "prop2": 999 },
    "item2": { "prop1": "qux", "prop2": 555 }
  }
};
console.log(validate(validData)); // 输出true

// 校验失败的示例数据(prop1重复)
const invalidData = {
  "obj2": {
    "item1": { "prop1": "baz", "prop2": 999 },
    "item2": { "prop1": "baz", "prop2": 555 }
  }
};
console.log(validate(invalidData)); // 输出false
console.log(validate.errors); // 打印错误信息

注意事项

  • 自定义关键字的逻辑可以根据需求调整:比如如果子对象必须包含prop1字段,可以在遍历的时候添加校验,没有该字段直接返回失败。
  • 如果需要支持更复杂的场景(比如嵌套多层对象、不同类型的prop1值),可以扩展自定义关键字的逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 21:40:22