I'm trying to map a json structure on Elasticsearch but something seems to be wrong because when I launch the curl command from my Windows prompt nothing appends except the underscore pulsing.
I use this curl command:
curl -H "Content-Type: application/json" -XPUT http://localhost:9200/technogym -d "{\"mappings\":{\"id\":{\"type\":\"string\"},\"key\":{\"type\":\"string\"},\"value\":{\"type\":\"object\",\"properties\":{\"rev\":{\"type\":\"string\"}}},\"doc\":{\"type\":\"object\",\"properties\":{\"_id\":{\"type\":\"string\"},\"_rev\":{\"type\":\"string\"},\"userID\":{\"type\":\"string\"},\"conversation_id\":{\"type\":\"string\"},\"input\":{\"type\":\"object\",\"properties\":{\"text\":{\"type\":\"string\"}}},\"output\":{\"type\":\"object\",\"properties\":{\"text\":{\"type\":\"string\"}}},\"node_visited\":{\"type\":\"string\"},\"intents\":{\"properties\":{\"intent\":{\"type\":\"string\"},\"confidence\":{\"type\":\"string\"}}},\"entities\":{\"type\":\"object\",\"properties\":{\"entity\":{\"type\":\"string\"},\"location\":{\"type\":\"string\"},\"value\":{\"type\":\"string\"},\"confidence\":{\"type\":\"string\"}}},\"timestamp\":{\"type\":\"date\"}}}}}"
Here my jsonwith mapping (just to make it more readable):
EDIT
{"mappings": {
"_default_": {
"properties": {
"id": {
"type": "string"
},
"key": {
"type": "string"
},
"value": {
"type": "object",
"properties": {
"rev": {
"type": "string"
}
}
},
"doc": {
"type": "object",
"properties": {
"_id": {
"type": "string"
},
"_rev": {
"type": "string"
},
"userID": {
"type": "string"
},
"conversation_id": {
"type": "string"
},
"input": {
"type": "object",
"properties": {
"text": {
"type": "string"
}
}
},
"output": {
"type": "object",
"properties": {
"text": {
"type": "string"
}
}
},
"node_visited": {
"type": "string"
},
"intents": {
"properties": {
"intent": {
"type": "string"
},
"confidence": {
"type": "string"
}
}
},
"entities": {
"type": "object",
"properties": {
"entity": {
"type": "string"
},
"location": {
"type": "string"
},
"value": {
"type": "string"
},
"confidence": {
"type": "string"
}
}
},
"timestamp": {
"type": "date"
}
}
}
}
}}}
I don't know why I can't upload this mapping.
Thanks for any help.
create an index
curl -XPUT localhost:9200/technogym
{"acknowledged":true}
Then apply your mapping to whatever type you want, eg. technogym_type
curl -X PUT localhost:9200/technogym/technogym_type/_mapping -d '{
"properties": {
"id": {
"type": "string"
},
"key": {
"type": "string"
},
"value": {
"type": "object",
"properties": {
"rev": {
"type": "string"
}
}
},
"doc": {
"type": "object",
"properties": {
"_id": {
"type": "string"
},
"_rev": {
"type": "string"
},
"userID": {
"type": "string"
},
"conversation_id": {
"type": "string"
},
"input": {
"type": "object",
"properties": {
"text": {
"type": "string"
}
}
},
"output": {
"type": "object",
"properties": {
"text": {
"type": "string"
}
}
},
"node_visited": {
"type": "string"
},
"intents": {
"properties": {
"intent": {
"type": "string"
},
"confidence": {
"type": "string"
}
}
},
"entities": {
"type": "object",
"properties": {
"entity": {
"type": "string"
},
"location": {
"type": "string"
},
"value": {
"type": "string"
},
"confidence": {
"type": "string"
}
}
},
"timestamp": {
"type": "date"
}
}
}
}
}'
{"acknowledged":true}
But if you dynamically want to create index and mappings, just fix your JSON document where it needs mappings (plural) and followed by the name of the type you want. (type equivalent to RDBMS table name)
curl -X PUT localhost:9200/technogym1 -d '
{
"mappings": {
"technogym_type1": {
"properties": {
"id": {
"type": "string"
},
"key": {
"type": "string"
},
"value": {
"type": "object",
"properties": {
"rev": {
"type": "string"
}
}
},
"doc": {
"type": "object",
"properties": {
"_id": {
"type": "string"
},
"_rev": {
"type": "string"
},
"userID": {
"type": "string"
},
"conversation_id": {
"type": "string"
},
"input": {
"type": "object",
"properties": {
"text": {
"type": "string"
}
}
},
"output": {
"type": "object",
"properties": {
"text": {
"type": "string"
}
}
},
"node_visited": {
"type": "string"
},
"intents": {
"properties": {
"intent": {
"type": "string"
},
"confidence": {
"type": "string"
}
}
},
"entities": {
"type": "object",
"properties": {
"entity": {
"type": "string"
},
"location": {
"type": "string"
},
"value": {
"type": "string"
},
"confidence": {
"type": "string"
}
}
},
"timestamp": {
"type": "date"
}
}
}
}
}
}
}'
{"acknowledged":true,"shards_acknowledged":true}
You need to change mapping to mappings.
{
"mappings": { ==> change this
"_default_": {
"properties": {
"id": {
"type": "string"
},
"key": {
"type": "string"
},
"value": {
"type": "object",
"properties": {
"rev": {
"type": "string"
}
}
},
"doc": {
"type": "object",
"properties": {
"_id": {
"type": "string"
},
"_rev": {
"type": "string"
},
"userID": {
"type": "string"
},
"conversation_id": {
"type": "string"
},
"input": {
"type": "object",
"properties": {
"text": {
"type": "string"
}
}
},
"output": {
"type": "object",
"properties": {
"text": {
"type": "string"
}
}
},
"node_visited": {
"type": "string"
},
"intents": {
"properties": {
"intent": {
"type": "string"
},
"confidence": {
"type": "string"
}
}
},
"entities": {
"type": "object",
"properties": {
"entity": {
"type": "string"
},
"location": {
"type": "string"
},
"value": {
"type": "string"
},
"confidence": {
"type": "string"
}
}
},
"timestamp": {
"type": "date"
}
}}}}}}
Related
it is possible to validate required values in a JSON Schema?
I have the following JSON:
{
"genericData": [
{
"name": "field_one",
"value": "data_one"
},
{
"name": "field_two",
"value": [
"array_data_one",
"array_data_two"
]
},
{
"name": "field_three",
"value": {
"attr_one": "some_data",
"attr_two": "more_data"
}
}
]
}
For validating the objects in the array i have the following JSON Schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"genericData": {
"type":"array",
"minItems": 2,
"items": [
{
"type": "object",
"if": {
"properties": {
"name": {
"enum": [
"field_one"
]
}
}
},
"then": {
"properties": {
"name": {
"type": "string"
},
"value": {
"type": "string"
}
}
}
},
{
"type": "object",
"if": {
"properties": {
"name": {
"enum": [
"field_two"
]
}
}
},
"then": {
"properties": {
"name": {
"type": "string"
},
"value": {
"type": "array",
"minItems": 1,
"items": [
{
"type": "string"
}
]
}
}
}
},
{
"type": "object",
"if": {
"properties": {
"name": {
"enum": [
"field_three"
]
}
}
},
"then": {
"properties": {
"name": {
"type": "string"
},
"value": {
"type": "object",
"properties": {
"attr_one": {
"type": "string"
},
"attr_two": {
"type": "string"
}
},
"required": [
"attr_one",
"attr_two"
]
}
}
}
}
]
}
}
}
Now my question is: Is it possible to set the objects e.g. with the names "field_one" and "field_two" as required? I tried to set the propertie "name", in the "then" clause as required, but this has no impact!
Thanks,
Andreas
I found the solution. The keywords "allOf" and "contains" in combination with "pattern" did what i want:
...
"genericData": {
"type":"array",
"minItems": 2,
"allOf": [
{
"contains": {
"type": "object",
"properties": {
"name": {
"type": "string",
"pattern": "^field_one$"
}
}
}
},
{
"contains": {
"type": "object",
"properties": {
"name": {
"type": "string",
"pattern": "^field_two$"
}
}
}
}
],
"items": [
{
"type": "object",
"if": {
"properties": {
"name": {
"enum": [
"field_one"
]
}
}
},
...
I have the following schema inside my Parse JSON action inside Power Automate Flow:-
{
"type": "object",
"properties": {
"_id": {
"type": "object",
"properties": {
"$oid": {
"type": "string"
}
}
},
"normalized_otherCategory": {
"type": "string"
},
"category": {
"type": "string"
},
"otherCategory": {
"type": "string"
},
"location": {
"type": "string"
},
"referenceNumber": {
"type": "string"
},
"archivingDate": {
"type": "object",
"properties": {
"$date": {
"type": "string"
}
}
},
"actions": {
"type": "array",
"items": {
"type": "object",
"properties": {
"_id": {
"type": "object",
"properties": {
"$oid": {
"type": "string"
}
}
},
"type": {
"type": "string"
},
"user": {
"type": "string"
},
"timestamp": {
"type": "object",
"properties": {
"$date": {
"type": "string"
}
}
},
"normalized_comment": {
"type": "array"
},
"configs": {
"type": "array"
},
"comment": {
"type": "string"
}
},
"required": [
"_id",
"type",
"user",
"timestamp",
"normalized_comment",
"configs"
]
}
},
"otherAttributes": {
"type": "array"
},
"attributes": {
"type": "array"
},
"timestamp": {
"type": "object",
"properties": {
"$date": {
"type": "string"
}
}
},
"foundDate": {
"type": "object",
"properties": {
"$date": {
"type": "string"
}
}
},
"trainFoundAt": {
"type": "object",
"properties": {
"number": {
"type": "string"
},
"car": {
"type": "string"
},
"seat": {
"type": "string"
}
}
},
"status": {
"type": "string"
},
"matchIdNumber": {
"type": "string"
},
"__v": {
"type": "integer"
},
"imageData": {
"type": "object",
"properties": {
"originalName": {
"type": "string"
},
"contentType": {
"type": "string"
},
"data": {
"type": "object",
"properties": {
"$binary": {
"type": "string"
},
"$type": {
"type": "string"
}
}
}
}
},
"imageThumbData": {
"type": "object",
"properties": {
"originalName": {
"type": "string"
},
"contentType": {
"type": "string"
},
"data": {
"type": "object",
"properties": {
"$binary": {
"type": "string"
},
"$type": {
"type": "string"
}
}
}
}
},
"stationFoundAt": {
"type": "string"
}
},
"required": [
"_id",
"normalized_otherCategory",
"category",
"location",
"referenceNumber",
"archivingDate",
"actions",
"otherAttributes",
"attributes",
"timestamp",
"foundDate",
"status",
"matchIdNumber",
"__v"
]
}
but it is raising this error on 5% of the items, while working well for the other 95% items:-
{
"errors": [
{
"message": "Invalid type. Expected String but got Null.",
"lineNumber": 0,
"linePosition": 0,
"path": "stationFoundAt",
"schemaId": "#/properties/stationFoundAt",
"errorType": "type",
"childErrors": []
}
]
}
here is a sample of one of the inputs which is raising this error:-
{
"content": {
"_id": {
"$oid": "5daa037cb66a2c601510e8aa"
},
"normalized_otherCategory": "purse,type,wallet",
"category": "other",
"otherCategory": "Purse-Type Wallet",
"location": "ontrain",
"referenceNumber": "VIAF-000009475",
"archivingDate": {
"$date": "2019-11-15T00:00:00.000Z"
},
"actions": [
{
"user": "PA454196",
"type": "created",
"_id": {
"$oid": "5daa037cb66a2c601510e8a9"
},
"timestamp": {
"$date": "2019-10-18T18:25:00.426Z"
},
"normalized_comment": [],
"configs": []
},
{
"_id": {
"$oid": "5daa037cb66a2c601510e8a8"
},
"user": "PA454196",
"comment": "",
"type": "comment",
"timestamp": {
"$date": "2019-10-18T18:25:00.425Z"
},
"normalized_comment": [],
"configs": []
},
{
"_id": {
"$oid": "5daa037cb66a2c601510e8a7"
},
"user": "PA454196",
"type": "stored",
"timestamp": {
"$date": "2019-10-18T18:25:00.425Z"
},
"normalized_comment": [],
"configs": [
"container-1",
"station-toronto"
]
},
{
"_id": {
"$oid": "5daa03b9b66a2c601510e8ab"
},
"user": "PA454196",
"type": "comment",
"comment": "black nylon",
"timestamp": {
"$date": "2019-10-18T00:00:00.000Z"
},
"normalized_comment": [
"black",
"nylon"
],
"configs": []
},
{
"_id": {
"$oid": "5db1d7481fccee641499efd1"
},
"user": "GR452944",
"type": "comment",
"comment": "pax lives in Australia. currently awaiting for Address and authorization to send to Australia from Management ",
"timestamp": {
"$date": "2019-10-24T00:00:00.000Z"
},
"normalized_comment": [
"pax",
"lives",
"in",
"australia",
"currently",
"awaiting",
"for",
"address",
"and",
"authorization",
"to",
"send",
"to",
"australia",
"from",
"management"
],
"configs": []
},
{
"comment": "Bryan Lim\n12/3 Rockley Road\nSouth Yarra\nVictoria \nAUSTRALIA 3141\n",
"type": "comment",
"user": "GR452944",
"_id": {
"$oid": "5db9d0d53da9956709808899"
},
"timestamp": {
"$date": "2019-10-30T00:00:00.000Z"
},
"normalized_comment": [
"bryan",
"lim",
"123",
"rockley",
"road",
"south",
"yarra",
"victoria",
"australia",
"3141"
],
"configs": []
},
{
"comment": "OCT 30- Sent by Canada Post, tracking number LX035418234CA",
"type": "comment",
"user": "CH454138",
"_id": {
"$oid": "5db9d73d8e450c67172d0dea"
},
"timestamp": {
"$date": "2019-10-30T00:00:00.000Z"
},
"normalized_comment": [
"oct",
"30",
"sent",
"by",
"canada",
"post",
"tracking",
"number",
"lx035418234ca"
],
"configs": []
}
],
"otherAttributes": [],
"attributes": [],
"timestamp": {
"$date": "2019-10-18T18:25:00.423Z"
},
"foundDate": {
"$date": "2019-10-16T00:00:00.000Z"
},
"trainFoundAt": {
"number": "55",
"car": "3323",
"seat": ""
},
"status": "opened",
"pnrNumber": "VWZ975",
"matchIdNumber": "",
"__v": 4,
"imageData": {
"originalName": "20191018_142530[1].jpg_big.jpg",
"contentType": "images/jpeg",
"data": {
"$binary": "/9j/*****5qTxPbNfy2t/dMp3oEVd2Oe4FUb/w9O0dvd3xd4VTYis+Qgz0zWW/ZUTalof02pLM266i8pVR2G4gCuo9o9vJB4fuEjV1LhjGhPKrj3rql0Ks/9k=",
"$type": "00"
}
},
"imageThumbData": {
"originalName": "20191018_142530[1].jpg_thumb.jpg",
"contentType": "images/jpeg",
"data": {
"$binary": "/9j/***SP/2Q==",
"$type": "00"
}
},
"stationFoundAt": null
},
"schema": {
"type": "object",
"properties": {
"_id": {
"type": "object",
"properties": {
"$oid": {
"type": "string"
}
}
},
"normalized_otherCategory": {
"type": "string"
},
"category": {
"type": "string"
},
"otherCategory": {
"type": "string"
},
"location": {
"type": "string"
},
"referenceNumber": {
"type": "string"
},
"archivingDate": {
"type": "object",
"properties": {
"$date": {
"type": "string"
}
}
},
"actions": {
"type": "array",
"items": {
"type": "object",
"properties": {
"_id": {
"type": "object",
"properties": {
"$oid": {
"type": "string"
}
}
},
"type": {
"type": "string"
},
"user": {
"type": "string"
},
"timestamp": {
"type": "object",
"properties": {
"$date": {
"type": "string"
}
}
},
"normalized_comment": {
"type": "array"
},
"configs": {
"type": "array"
},
"comment": {
"type": "string"
}
},
"required": [
"_id",
"type",
"user",
"timestamp",
"normalized_comment",
"configs"
]
}
},
"otherAttributes": {
"type": "array"
},
"attributes": {
"type": "array"
},
"timestamp": {
"type": "object",
"properties": {
"$date": {
"type": "string"
}
}
},
"foundDate": {
"type": "object",
"properties": {
"$date": {
"type": "string"
}
}
},
"trainFoundAt": {
"type": "object",
"properties": {
"number": {
"type": "string"
},
"car": {
"type": "string"
},
"seat": {
"type": "string"
}
}
},
"status": {
"type": "string"
},
"matchIdNumber": {
"type": "string"
},
"__v": {
"type": "integer"
},
"imageData": {
"type": "object",
"properties": {
"originalName": {
"type": "string"
},
"contentType": {
"type": "string"
},
"data": {
"type": "object",
"properties": {
"$binary": {
"type": "string"
},
"$type": {
"type": "string"
}
}
}
}
},
"imageThumbData": {
"type": "object",
"properties": {
"originalName": {
"type": "string"
},
"contentType": {
"type": "string"
},
"data": {
"type": "object",
"properties": {
"$binary": {
"type": "string"
},
"$type": {
"type": "string"
}
}
}
}
},
"stationFoundAt": {
"type": "string"
}
},
"required": [
"_id",
"normalized_otherCategory",
"category",
"location",
"referenceNumber",
"archivingDate",
"actions",
"otherAttributes",
"attributes",
"timestamp",
"foundDate",
"status",
"matchIdNumber",
"__v"
]
}
}
here is a JSON which was parsed successfully:-
{
"content": {
"_id": {
"$oid": "5dde57bffeaf3f770907b144"
},
"normalized_otherCategory": "books,of,numbers",
"category": "books",
"otherCategory": "books of numbers",
"location": "ontrain",
"referenceNumber": "VIAF-000010334",
"archivingDate": {
"$date": "2020-02-24T00:00:00.000Z"
},
"actions": [
{
"_id": {
"$oid": "5dde57bffeaf3f770907b143"
},
"type": "created",
"user": "SO202505",
"timestamp": {
"$date": "2019-11-27T11:02:23.899Z"
},
"normalized_comment": [],
"configs": []
},
{
"type": "comment",
"comment": "",
"user": "SO202505",
"_id": {
"$oid": "5dde57bffeaf3f770907b142"
},
"timestamp": {
"$date": "2019-11-27T11:02:23.899Z"
},
"normalized_comment": [],
"configs": []
},
{
"type": "stored",
"user": "SO202505",
"_id": {
"$oid": "5dde57bffeaf3f770907b141"
},
"timestamp": {
"$date": "2019-11-27T11:02:23.899Z"
},
"normalized_comment": [],
"configs": [
"container-2",
"station-quebec"
]
}
],
"otherAttributes": [],
"attributes": [],
"timestamp": {
"$date": "2019-11-27T11:02:23.898Z"
},
"foundDate": {
"$date": "2019-11-26T00:00:00.000Z"
},
"trainFoundAt": {
"number": "28",
"car": "3",
"seat": "12c"
},
"status": "opened",
"pnrNumber": "",
"matchIdNumber": "",
"__v": 0,
"imageData": {
"originalName": "WIN_20191127_05_55_39_Pro.jpg_big.jpg",
"contentType": "images/jpeg",
"data": {
"$binary": "/9j/2****oI2SuUUUI/sRZ//9k=",
"$type": "00"
}
},
"imageThumbData": {
"originalName": "WIN_20191127_05_55_39_Pro.jpg_thumb.jpg",
"contentType": "images/jpeg",
"data": {
"$binary": "/9j/****Bn//2Q==",
"$type": "00"
}
}
},
"schema": {
"type": "object",
"properties": {
"_id": {
"type": "object",
"properties": {
"$oid": {
"type": "string"
}
}
},
"normalized_otherCategory": {
"type": "string"
},
"category": {
"type": "string"
},
"otherCategory": {
"type": "string"
},
"location": {
"type": "string"
},
"referenceNumber": {
"type": "string"
},
"archivingDate": {
"type": "object",
"properties": {
"$date": {
"type": "string"
}
}
},
"actions": {
"type": "array",
"items": {
"type": "object",
"properties": {
"_id": {
"type": "object",
"properties": {
"$oid": {
"type": "string"
}
}
},
"type": {
"type": "string"
},
"user": {
"type": "string"
},
"timestamp": {
"type": "object",
"properties": {
"$date": {
"type": "string"
}
}
},
"normalized_comment": {
"type": "array"
},
"configs": {
"type": "array"
},
"comment": {
"type": "string"
}
},
"required": [
"_id",
"type",
"user",
"timestamp",
"normalized_comment",
"configs"
]
}
},
"otherAttributes": {
"type": "array"
},
"attributes": {
"type": "array"
},
"timestamp": {
"type": "object",
"properties": {
"$date": {
"type": "string"
}
}
},
"foundDate": {
"type": "object",
"properties": {
"$date": {
"type": "string"
}
}
},
"trainFoundAt": {
"type": "object",
"properties": {
"number": {
"type": "string"
},
"car": {
"type": "string"
},
"seat": {
"type": "string"
}
}
},
"status": {
"type": "string"
},
"matchIdNumber": {
"type": "string"
},
"__v": {
"type": "integer"
},
"imageData": {
"type": "object",
"properties": {
"originalName": {
"type": "string"
},
"contentType": {
"type": "string"
},
"data": {
"type": "object",
"properties": {
"$binary": {
"type": "string"
},
"$type": {
"type": "string"
}
}
}
}
},
"imageThumbData": {
"type": "object",
"properties": {
"originalName": {
"type": "string"
},
"contentType": {
"type": "string"
},
"data": {
"type": "object",
"properties": {
"$binary": {
"type": "string"
},
"$type": {
"type": "string"
}
}
}
}
},
"stationFoundAt": {
"type": "string"
}
},
"required": [
"_id",
"normalized_otherCategory",
"category",
"location",
"referenceNumber",
"archivingDate",
"actions",
"otherAttributes",
"attributes",
"timestamp",
"foundDate",
"status",
"matchIdNumber",
"__v"
]
}
}
can anyone advice how i can fix this error for the 5% of the items?
Thanks
For string properties that can be null the type declaration should be defined as { "type": ["string", "null"] }.
Here is my JSON schema and JSON as shown below at the bottom and using ajv validator to support json spec draft 7.
By default, the 'science' object must be represented as:
//Default science object
{"type": "science", "rule": {"sciencePattern": {}}}
where the 'rule' and 'sciencePattern' MUST be there.
However, if the 'sciencePattern' about to contains other attributes (as per the schema), then the below validation should kick in:
If the default science object is present, then the "scored" attributes in "arts" object should be REQUIRED.
If the NESTED "scored" array attribute is present within rule as:
{ "type": "science", "rule":{"sciencePattern":{"marks":{"scored":[10]}}} }
then the "scored" attributes in "arts" object should not be REQUIRED. In other words, if some one specify "scored" attribute withn the "arts" object, the schema validation should complain as there is a "scored" attribute is available in "science" object.
//JSON Schema
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": [
"exam"
],
"properties": {
"exam": {
"type": "array",
"minItems": 1,
"items": {
"anyOf": [
{
"$ref": "#/definitions/science"
},
{
"$ref": "#/definitions/arts"
}
]
}
},
"if": {
"type": "object",
"required": [
"type",
"rule"
],
"properties": {
"type": {
"const": "science"
},
"rule": {
"type": "object",
"required": [
"sciencePattern"
],
"properties": {
"sciencePattern": {
"$ref": "#/definitions/sciencePattern"
}
}
}
}
},
"then": {
"type": "object",
"required": [
"type"
],
"properties": {
"type": {
"const": "arts"
},
"not": {
"required": [
"scored"
]
}
}
}
},
"definitions": {
"sciencePattern": {
"type": "object",
"required": [
"marks"
],
"properties": {
"marks": {
"type": "object",
"required": [
"scored"
],
"properties": {
"scored": {
"type": "array"
}
}
}
}
},
"science": {
"type": "object",
"properties": {
"type": {
"const": "science"
},
"rule": {
"required": [
"sciencePattern"
],
"properties": {
"sciencePattern": {
"$ref": "#/definitions/sciencePattern"
}
}
}
}
},
"arts": {
"required": [
"scored"
],
"properties": {
"type": {
"const": "arts"
},
"scored": {
"type": "number"
},
"remarks": {
"type": "string"
}
}
}
}
}
and My JSON
{
"exam": [
{
"type": "science",
"rule": {
"sciencePattern": {
"marks": {
"scored": [10]
}
}
}
},
{
"type": "arts",
"scored": 10 //This should complain as 'scored' is available above in science
}
]
}
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": [
"exam"
],
"properties": {
"exam": {
"type": "array",
"allOf":[
{
"if": {
"contains": {
"type": "object",
"required": [
"type"
],
"properties": {
"type": {
"const": "science"
}
}
}
},
"then":{
"required":["rule", "sciencePattern"]
}
},
{
"if": {
"contains": {
"type": "object",
"required":["type","rule", "sciencePattern"],
"properties": {
"type": {
"const": "science"
}
}
}
},
"then":{
"required":["scored"]
}
},
{
"if": {
"contains": {
"type": "object",
"required": [
"type",
"rule"
],
"properties": {
"type": {
"const": "science"
},
"rule": {
"type": "object",
"required": [
"sciencePattern"
],
"properties": {
"sciencePattern": {
"$ref": "#/definitions/emptySciencePattern"
}
}
}
}
}
},
"then": {
"contains": {
"type": "object",
"required": ["type", "scored"],
"properties": {
"type": {
"const": "arts"
}
}
}
},
"else": {
"if": {
"contains": {
"type": "object",
"required": [
"type",
"rule"
],
"properties": {
"type": {
"const": "science"
},
"rule": {
"type": "object",
"required": [
"sciencePattern"
],
"properties": {
"sciencePattern": {
"$ref": "#/definitions/sciencePattern"
}
}
}
}
}
},
"then": {
"contains": {
"required": [
"type"
],
"properties": {
"type": {
"const": "arts"
}
},
"not": {
"required": ["scored"]
}
}
}
}
}],
"minItems": 1,
"items": {
"anyOf": [{
"$ref": "#/definitions/science"
}, {
"$ref": "#/definitions/arts"
}]
}
}
},
"definitions": {
"rule": {
"type": "object",
"required": ["sciencePattern"],
"properties": {
"sciencePattern": {
"$ref": "#/definitions/sciencePattern"
}
}
},
"emptySciencePattern": {
"type": "object",
"maxProperties": 0,
"additionalProperties": false,
"properties": {}
},
"sciencePattern": {
"type": "object",
"properties": {
"marks": {
"type": "object",
"properties": {
"scored": {
"type": "array"
}
}
}
}
},
"science": {
"type": "object",
"required": ["rule"],
"properties": {
"type": {
"const": "science"
},
"rule": {
"$ref":"#/definitions/rule"
}
}
},
"arts": {
"properties": {
"type": {
"const": "arts"
},
"scored": {
"type": "number"
},
"remarks": {
"type": "string"
}
}
}
}
}
Here is the criteria: the individual region object can co-exist withing the array along with ONLY asia/europe/austrlia (either one region at a time from asia/europe/austrlia).
In addition to this every region object can have few required attributes and nested one.
The issue is the schema validator is not complaining about the required attribute (i.e. width attribute from dimension object)
Here is the JSON Schema
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"stat_data": {
"type": "array",
"if": {
"contains": {
"type": "object",
"properties": {
"region": {
"type": "string",
"enum": [
"europe"
]
}
}
}
},
"then": {
"not": {
"contains": {
"type": "object",
"properties": {
"region": {
"type": "string",
"enum": [
"asia",
"australia"
]
}
}
}
}
},
"else": {
"if": {
"contains": {
"type": "object",
"properties": {
"region": {
"type": "string",
"enum": [
"asia"
]
}
}
}
},
"then": {
"not": {
"contains": {
"type": "object",
"properties": {
"region": {
"type": "string",
"enum": [
"europe",
"australia"
]
}
}
}
}
},
"else": {
"if": {
"contains": {
"type": "object",
"properties": {
"region": {
"type": "string",
"enum": [
"australia"
]
}
}
}
},
"then": {
"not": {
"contains": {
"type": "object",
"properties": {
"region": {
"type": "string",
"enum": [
"europe",
"asia"
]
}
}
}
}
},
"else": {}
}
},
"items": {
"type": "object",
"properties": {
"details": {
"$ref": "#/definitions/dimension"
},
"population": {
"$ref": "#/definitions/details"
},
"dimension": {
"$ref": "#/definitions/population"
},
"region": {
"enum": [
"asia",
"europe",
"australia",
"some-pencil-region",
"some-oil-pastels-region"
]
}
}
}
}
},
"definitions": {
"dimension": {
"type": "object",
"required": [
"width"
],
"properties": {
"height": {
"type": "integer"
},
"width": {
"type": "integer"
}
}
},
"details": {
"type": "object",
"properties": {
"brand": {
"type": "string"
},
"year": {
"type": "integer"
}
}
},
"population": {
"type": "object",
"properties": {
"change": {
"type": "integer"
},
"year": {
"type": "integer"
}
}
}
}
}
and the JSON
{
"stat_data": [
{
"region": "some-pencil-region",
"details": {
"brand": "Camlin",
"year": 2019
}
},
{
"region": "some-oil-pastels-region",
"height": 30
},
{
"region": "asia",
"population": {
"year": 2018,
"change": 2
}
}
]
}
You can check at _https://jsonschema.dev/ by copying schema and json in the editor
Maybe your JSON validator doesn't catch the issue? JSONBuddy shows a message about a missing "width" property:
I have a program that I have built that takes a JSON object and produces a JSON schema file based on the details of the input. When I use this program to generate a schema for a smaller JSON object, the schema works correctly and validates as expected. In this smaller schema there is only one if-then-else block.
However when I attempt to generate a schema that makes use of several if-then-else blocks the if-then-else validation seems to stop working at all and will allow anything through.
I'll post an example below to be more clear.
JSON Schema
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"question6-99": {
"type": "object",
"properties": {
"answer": {
"type": "string",
"enum": ["Yes", "No"]
}
}
},
"question6-100": {
"type": "object",
"properties": {
"answer": {
"type": "string",
"enum": ["Mr","Ms","Mrs","Miss","Dr","Rev","Sir","Lady","Lord","Prof", ""]
}
}
}
},
"type": "object",
"properties": {
"form_submission": {
"type": "object",
"properties": {
"sections": {
"type": "object",
"properties": {
"6": {
"type": "object",
"properties": {
"questions": {
"type": "object",
"properties": {
"99": {
"$ref": "#/definitions/question6-99"
},
"100": {
"$ref": "#/definitions/question6-100"
}
},
"if": {
"properties": {
"99": {
"properties": {
"answer": {
"enum": [
"Yes"
]
}
},
"required": [
"answer"
]
}
},
"required": [
"100"
]
},
"then": {
"properties": {
"100": {
"properties": {
"answer": {
"minLength": 1
}
}
}
}
},
"else": {
"properties": {
"100": {
"properties": {
"answer": {
"maxLength": 0
}
}
}
}
}
}
}
}
},
"required": [
"6"
]
}
}
}
}
}
JSON Object being validated
{
"form_submission": {
"sections": {
"1": {
"questions": {
"99": {
"answer": "Yes",
},
"100": {
"answer": "",
}
}
}
}
}
}
For the above example, if the schema is used to validate the object, the answer for question 100 must be answered when question 99 is answered "yes". This works correctly.
However if I then attempt to use the schema below, which uses two if-then-else blocks against the second JSON object, no if-then-else validation occurs.
I'm just wondering if I have done something wrong with the structure of my schema code that is stopping the validation from happening correctly.
Schema using two If-then-else
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"question6-99": {
"type": "object",
"properties": {
"answer": {
"type": "string",
"minLength": 1,
"enum": ["Yes", "No"]
}
}
},
"question6-100": {
"type": "object",
"properties": {
"answer": {
"type": "string",
"enum": ["Mr", "Ms", "Mrs", "Miss", "Dr", "Rev", "Sir", "Lady", "Lord", "Prof", ""]
}
}
},
"question6-101": {
"type": "object",
"properties": {
"answer": {
"type": "string"
}
}
}
},
"type": "object",
"properties": {
"form_submission": {
"type": "object",
"properties": {
"sections": {
"type": "object",
"properties": {
"6": {
"type": "object",
"properties": {
"questions": {
"type": "object",
"properties": {
"99": {
"$ref": "#/definitions/question6-99"
},
"100": {
"$ref": "#/definitions/question6-100"
},
"101": {
"$ref": "#/definitions/question6-101"
}
},
"required": ["99", "100", "101", "102", "103", "104", "105", "111"],
"if": {
"properties": {
"99": {
"properties": {
"answer": {
"enum": ["Yes"]
}
},
"required": ["answer"]
}
},
"required": ["100"]
},
"then": {
"properties": {
"100": {
"properties": {
"answer": {
"minLength": 1
}
}
}
}
},
"else": {
"properties": {
"100": {
"properties": {
"answer": {
"maxLength": 0
}
}
}
}
},
"if": {
"properties": {
"99": {
"properties": {
"answer": {
"enum": ["Yes"]
}
},
"required": ["answer"]
}
},
"required": ["101"]
},
"then": {
"properties": {
"101": {
"properties": {
"answer": {
"minLength": 1
}
}
}
}
},
"else": {
"properties": {
"101": {
"properties": {
"answer": {
"maxLength": 0
}
}
}
}
}
}
}
}
},
"required": ["1"]
}
}
}
}
}
Second schema to validate
{
"form_submission": {
"id": "80035",
"status": "Incomplete",
"validated": true,
"failure_reason": "",
"sections": {
"1": {
"questions": {
"99": {
"answer": "Yes",
"web_validated": true,
"web_error_string": "",
"server_error_string": ""
},
"100": {
"answer": "",
"web_validated": true,
"web_error_string": "",
"server_error_string": ""
},
"101": {
"answer": "Yes",
"web_validated": true,
"web_error_string": "",
"server_error_string": ""
}
},
"name": "",
"validated": true,
"server_validated": true,
"notes": ""
}
},
"submitted_section_id": 11
}
}
Added allOf to Schema
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"question6-99": {
"type": "object",
"properties": {
"answer": {
"type": "string",
"minLength": 1,
"enum": ["Yes", "No"]
}
}
},
"question6-100": {
"type": "object",
"properties": {
"answer": {
"type": "string",
"enum": ["Mr", "Ms", "Mrs", "Miss", "Dr", "Rev", "Sir", "Lady", "Lord", "Prof", ""]
}
}
},
"question6-101": {
"type": "object",
"properties": {
"answer": {
"type": "string"
}
}
}
},
"type": "object",
"properties": {
"form_submission": {
"type": "object",
"properties": {
"sections": {
"type": "object",
"properties": {
"6": {
"type": "object",
"properties": {
"questions": {
"type": "object",
"properties": {
"99": {
"$ref": "#/definitions/question6-99"
},
"100": {
"$ref": "#/definitions/question6-100"
},
"101": {
"$ref": "#/definitions/question6-101"
}
},
"required": ["99", "100", "101", "102", "103", "104", "105", "111"],
"allOf": [
{
"if": {
"properties": {
"99": {
"properties": {
"answer": {
"enum": ["Yes"]
}
},
"required": ["answer"]
}
},
"required": ["100"]
},
"then": {
"properties": {
"100": {
"properties": {
"answer": {
"minLength": 1
}
}
}
}
},
"else": {
"properties": {
"100": {
"properties": {
"answer": {
"maxLength": 0
}
}
}
}
}},
{
"if": {
"properties": {
"99": {
"properties": {
"answer": {
"enum": ["Yes"]
}
},
"required": ["answer"]
}
},
"required": ["101"]
},
"then": {
"properties": {
"101": {
"properties": {
"answer": {
"minLength": 1
}
}
}
}
},
"else": {
"properties": {
"101": {
"properties": {
"answer": {
"maxLength": 0
}
}
}
}
}
}
]
}
}
}
},
"required": ["1"]
}
}
}
}
}
If we remove the complicated bits, I think the problem becomes clear.
{
"if": { ... },
"then": { ... },
"if": { ... },
"then": { ... }
}
In JSON the value of duplicated keys is undefined. One of these ifs and one of these thens will be ignored by a JSON parser.
You can get around this problem by wrapping your ifs in an allOf.
{
"allOf": [
{
"if": { ... },
"then": { ... }
},
{
"if": { ... },
"then": { ... }
}
]
}
It's good practice to always wrap your if/then/else in allOf even if you have only one. This is because a JSON object is by definition unordered. Therefore, some tool might rearrange your keywords splitting up the ifs and thens in a way that makes the schema difficult to decipher.
{
"definitions": {},
"else": {},
"if": {},
"properties": {},
"then": {},
"type": "object",
}