使用 AJV 要求某些元素存在于数组中

Requiring certain elements to exist in an array using AJV

我想使用模式验证 JSON 对象,以确保模式中指定的所有元素都存在于数组中。例如,我的人员数组必须包含这些人:

{
  "people":[
    {
      "name":"Bob",
      "age":"26"
    },
    {
      "name":"Jim",
      "age":"35"
    },
    {
      "name":"John",
      "age":"27"
    }
  ]
}

任何其他人都将被忽略,但这些人必须存在。我尝试在项目说明符中使用 allOf 但它失败了,因为 allOf 指定每个元素应该匹配每个提供的模式。

{
  "people":{
    "type":"array",
    "items":{
      "allOf":[
        {
          "type":"object",
          "properties":{
            "name":{
              "type":"string",
              "const":"Bob"
            },
            "age":{
              "type":"string",
              "const":"26"
            }
          },
          "required":[
            "name",
            "age"
          ]
        },
        {
          "type":"object",
          "properties":{
            "name":{
              "type":"string",
              "const":"Jim"
            },
            "age":{
              "type":"string",
              "const":"35"
            }
          },
          "required":[
            "name",
            "age"
          ]
        },
        {
          "type":"object",
          "properties":{
            "name":{
              "type":"string",
              "const":"John"
            },
            "age":{
              "type":"string",
              "const":"27"
            }
          },
          "required":[
            "name",
            "age"
          ]
        }
      ]
    }
  }
}

根据这些信息,我们可以得出结论,有效的人员数组为:

  [
    {
      "name":"Bob",
      "age":"26"
    },
    {
      "name":"Jim",
      "age":"35"
    },
    {
      "name":"John",
      "age":"27"
    },
    {
      "name":"Tim",
      "age":"47"
    }
  ]

无效数组为:

  [
    {
      "name":"Bob",
      "age":"26"
    },
    {
      "name":"Jim",
      "age":"35"
    },
    {
      "name":"Tim",
      "age":"47"
    }
  ]

因为列表中缺少 John。

这是 AJV 文件的代码。

const Ajv = require('ajv');
const jsonInput = require('./people.json');
const schema = require('./peopleSchema.json');

const ajv = new Ajv();
const validate = ajv.compile(schema);
const valid = validate(jsonInput);

console.log(valid);

if (!valid) console.log(validate.errors);

如上所述,我会使用什么 属性 来指定数组中需要哪些元素?

编辑:根据评论,我尝试使用 contains 但没有成功。

{
  "$id": "root",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "people": {
      "type": "array",
      "items": {
        "type": "object",
        "allOf": [
          {
            "contains": {
              "properties": {
                "name": {
                  "enum": ["Bob"]
                },
                "age": {
                  "enum": ["26"]
                }
              }
            }
          },
          {
            "contains": {
              "properties": {
                "name": {
                  "enum": ["John"]
                },
                "age": {
                  "enum": ["27"]
                }
              }
            }
          },
          {
            "contains": {
              "properties": {
                "name": {
                  "enum": ["Jim"]
                },
                "age": {
                  "enum": ["36"]
                }
              }
            }
          }
        ]
      }
    }
  },
  "required": ["people"]
}

我能够通过将以下内容用作架构来满足我的要求。

{
  "properties": {
    "people": {
      "items": {
        "properties": {
            "name": { "type": "string" },
            "age": { "type": "string" }
        }
      },
      "allOf": [
        {
          "contains": {
            "const": {
                "name": "Bob",
                "color": "26"
            }
          }
        },
        {
          "contains": {
            "const": {
                "name": "Jim",
                "color": "35"
            }
          }
        },
        {
          "contains": {
            "const": {
                "name": "John",
                "color": "27"
            }
          }
        }
        ]
    }
  },
  "required": [
    "people"
  ],
  "additionalProperties": false
}