Why is the conditional subschema (JSON Schema Draft7) validation not working? - powershell

Ref: https://json-schema.org/understanding-json-schema/reference/conditionals.html
- Schema snippet
"properties": {
"country": {
"default": "United States of America",
"enum": [
"United States of America",
"Canada"
]
},
"address": {
"properties": {
"AddressLine1": {
"type": "string"
},
"if": {
"properties": {
"country": {
"const": "United States of America"
}
}
},
"then": {
"postal_code": {
"type": "integer"
}
},
"else": {
"postal_code": {
"type": "string"
}
}
},
"required": [
"AddressLine1",
"postal_code"
]
Sample Data 1 - Expected Pass
{
"address": {
"AddressLine1": "Address Line 1 in US",
"postal_code": 11779
}
}
Sample Data 2 - Expected Fail
{
"address": {
"AddressLine1": "Address Line 1 in Canada",
"postal_code": "RA90 188"
}
}
I expected the 2nd sample to fail but it passes without any issues. I am using PowerShell Test-JSON for validation

You forgot to wrap postal_code in "properties": { ... } in your then and else clauses.

Related

Can Redoc display "if" - "then" conditions in schema documentation?

I am working on an API documentation using Redoc where I have some conditionals (if-then) in the JSON Schema. I am trying to get this through in the API documentation, but the Redoc documentation does not show this.
As an example I have used the if-then-else method showcased here: https://json-schema.org/understanding-json-schema/reference/conditionals.html
by wrapping pairs of if and then inside an allOf. This is the JSON Schema after doing that:
{
"type": "object",
"properties": {
"street_address": {
"type": "string"
},
"country": {
"default": "United States of America",
"enum": ["United States of America", "Canada", "Netherlands"]
}
},
"allOf": [
{
"if": {
"properties": { "country": { "const": "United States of America" } }
},
"then": {
"properties": { "postal_code": { "pattern": "[0-9]{5}(-[0-9]{4})?" } }
}
},
{
"if": {
"properties": { "country": { "const": "Canada" } },
"required": ["country"]
},
"then": {
"properties": { "postal_code": { "pattern": "[A-Z][0-9][A-Z] [0-9][A-Z][0-9]" } }
}
},
{
"if": {
"properties": { "country": { "const": "Netherlands" } },
"required": ["country"]
},
"then": {
"properties": { "postal_code": { "pattern": "[0-9]{4} [A-Z]{2}" } }
}
}
]
}
Redoc just displays this as:
With no mention to the if-then statements. Can that be achieved?

How to group by single field and return more values together

I'm starting to use apache druid but having some difficult to run native queries (and some SQL too).
1- Is it possible to groupBy a single column while also returning more channels?
2- How could I groupBy a single column, while returning different grouped itens on same query/row ?
Query I'm trying to use:
{
"queryType": "groupBy",
"dataSource": "my-data-source",
"granularity": "all",
"intervals": ["2022-06-27T03:00:00.000Z/2022-06-28T03:00:00.000Z"],
"context:": { "timeout: 30000 },
"dimensions": ["userId"],
"filter": {
"type": "and",
"fields": [
{
"type": "or",
"fields": [{...}]
}
]
},
"aggregations": [
{
"type": "count",
"name": "count"
}
]
}
Tried to add a filtered type inside aggregations:[] but 0 changes happened.
"aggregations": [
{
"type: "count",
"name": "count"
},
{
"type": "filtered",
"filter": {
"type": "selector",
"dimension": "block_id",
"value": "block1"
},
"aggregator": {
"type": "count",
"name": "block1",
"fieldName": "block_id"
}
}
]
Grouping Aggregator also didn't work.
"aggregations": [
{
"type": "count",
"name": "count"
},
{
"type": "grouping",
"name": "groupedData",
"groupings": ["block_id"]
}
],
Below is the image illustrating the results I'm trying to achieve.
Not sure yet how to get the results in the format you want, but as a start, something like this might be a step:
{
"queryType": "groupBy",
"dataSource": {
"type": "table",
"name": "dataTest"
},
"intervals": {
"type": "intervals",
"intervals": [
"-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z"
]
},
"filter": null,
"granularity": {
"type": "all"
},
"dimensions": [
{
"type": "default",
"dimension": "d2_ts2",
"outputType": "STRING"
},
{
"type": "default",
"dimension": "d3_email",
"outputType": "STRING"
}
],
"aggregations": [
{
"type": "count",
"name": "myCount",
}
],
"descending": false
}
I'm curious, what is the use case?
Using a SQL query you can do it this way:
SELECT UserID,
sum(1) FILTER (WHERE BlockId = 'block1') as Block1,
sum(1) FILTER (WHERE BlockId = 'block2') as Block2,
sum(1) FILTER (WHERE BlockId = 'block3') as Block3
FROM inline_data
GROUP BY 1
The Native Query for this (from the explain) is:
{
"queryType": "topN",
"dataSource": {
"type": "table",
"name": "inline_data"
},
"virtualColumns": [
{
"type": "expression",
"name": "v0",
"expression": "1",
"outputType": "LONG"
}
],
"dimension": {
"type": "default",
"dimension": "UserID",
"outputName": "d0",
"outputType": "STRING"
},
"metric": {
"type": "dimension",
"previousStop": null,
"ordering": {
"type": "lexicographic"
}
},
"threshold": 101,
"intervals": {
"type": "intervals",
"intervals": [
"-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z"
]
},
"filter": null,
"granularity": {
"type": "all"
},
"aggregations": [
{
"type": "filtered",
"aggregator": {
"type": "longSum",
"name": "a0",
"fieldName": "v0",
"expression": null
},
"filter": {
"type": "selector",
"dimension": "BlockId",
"value": "block1",
"extractionFn": null
},
"name": "a0"
},
{
"type": "filtered",
"aggregator": {
"type": "longSum",
"name": "a1",
"fieldName": "v0",
"expression": null
},
"filter": {
"type": "selector",
"dimension": "BlockId",
"value": "block2",
"extractionFn": null
},
"name": "a1"
},
{
"type": "filtered",
"aggregator": {
"type": "longSum",
"name": "a2",
"fieldName": "v0",
"expression": null
},
"filter": {
"type": "selector",
"dimension": "BlockId",
"value": "block3",
"extractionFn": null
},
"name": "a2"
}
],
"postAggregations": [],
"context": {
"populateCache": false,
"sqlOuterLimit": 101,
"sqlQueryId": "bb92e899-c127-49b0-be1b-d4b38909d166",
"useApproximateCountDistinct": false,
"useApproximateTopN": false,
"useCache": false,
"useNativeQueryExplain": true
},
"descending": false
}

Add weather WebPart using Add-PnPClientSideWebPart is not setting location

I'm trying to add a weather WebPart on a modern page in SharePoint Online.
This is the PowerShell I'm executing:
$jsonProperties = '
{
"serverProcessedContent": {
"searchablePlainTexts": {
"webPartTitle": "Weather"
}
},
"properties": {
"temperatureUnit": "C",
"locations": [
{
"countryName": "Australia",
"name": "Manjimup, Australia",
"latitude": -34.24055862426758,
"longitude": 116.14610290527344,
"showCustomizedDisplayName": false
},
{
"countryName": "Australia",
"name": "Bega, Australia",
"latitude": -36.673919677734378,
"longitude": 149.84178161621095,
"showCustomizedDisplayName": false
}
]
}
}'
Add-PnPClientSideWebPart -Page https://mysharepointsite.sharepoint.com/Sites/MyPage -DefaultWebPartType Weather -WebPartProperties $jsonProperties
The WebPart is being added but there are no weather locations, as shown below.
What am I missing for the locations to be added to the WebPart?
I was missing the property "dataVersion": "1.2". The full JSON looks like this:
$jsonProperties = '
{
"dataVersion": "1.2",
"serverProcessedContent": {
"searchablePlainTexts": {
"webPartTitle": "Weather"
}
},
"properties": {
"temperatureUnit": "C",
"locations": [
{
"countryName": "Australia",
"name": "Manjimup, Australia",
"latitude": -34.24055862426758,
"longitude": 116.14610290527344,
"showCustomizedDisplayName": false
},
{
"countryName": "Australia",
"name": "Bega, Australia",
"latitude": -36.673919677734378,
"longitude": 149.84178161621095,
"showCustomizedDisplayName": false
}
]
}
}'

Optional object with required fields in react-jsonschema-form

Given a json schema like the one below, the react-jsonschema-form validator essentially requires both shipping_address and billing_address even though the billing_address is not listed as required. This is because the address type requires all three of its properties. How can I make the billing_address optional? It seems that react-jsonschema-form should simply no submit billing_address if not all of its address properties are filled in. Here is a link to the react-jsonschema-form playground.
{
"definitions": {
"address": {
"type": "object",
"properties": {
"street_address": {
"type": "string"
},
"city": {
"type": "string"
},
"state": {
"type": "string"
}
},
"required": [
"street_address",
"city",
"state"
]
}
},
"type": "object",
"properties": {
"billing_address": {
"title": "Billing address",
"$ref": "#/definitions/address"
},
"shipping_address": {
"title": "Shipping address",
"$ref": "#/definitions/address"
}
},
"required": [
"shipping_address"
]
}
You can use dynamic schema dependencies to make the billing address conditionally displayed and required. This isn't the same as having an optional object but seem to suffice if you're willing to have a slightly different user experience. Here is a link to the react-jsonschema-form playground. It is best viewed, in my opinion, with live validation disabled (there's a checkbox in the upper-right of the page).
{
"definitions": {
"address": {
"type": "object",
"properties": {
"street_address": {
"type": "string"
},
"city": {
"type": "string"
},
"state": {
"type": "string"
}
},
"required": [
"street_address",
"city",
"state"
]
}
},
"type": "object",
"properties": {
"different_addresses": {
"title": "My billing address is different than my shipping address.",
"type": "boolean",
"default": false
},
"shipping_address": {
"title": "Shipping address",
"$ref": "#/definitions/address"
}
},
"required": [
"shipping_address"
],
"dependencies": {
"different_addresses": {
"oneOf": [
{
"properties": {
"different_addresses": {
"enum": [
false
]
}
}
},
{
"properties": {
"different_addresses": {
"enum": [
true
]
},
"billing_address": {
"title": "Billing address",
"$ref": "#/definitions/address"
}
},
"required": [
"billing_address"
]
}
]
}
}
}
my question is related to your JSON schema.
I need to target the "grandchild" of a parent object for a dependency.
Is this possible? In case of "different_addresses" being an object.
For example:
"dependencies": {
"different_addresses": {
"properties": {
"OTHER_FIELD": {
"oneOf": [
{
"properties": {
"different_addresses": {
"properties": {
"OTHER_FIELD": {
"enum": [
false
]
}
}
}
}
}
]
}
}
}
}

How can I use CloudKit web services to query based on a reference field?

I've got two CloudKit data objects that look somewhat like this:
Parent Object:
{
"records": [
{
"recordName": "14102C0A-60F2-4457-AC1C-601BC628BF47-184-000000012D225C57",
"recordType": "ParentObject",
"fields": {
"fsYear": {
"value": "2015",
"type": "STRING"
},
"displayOrder": {
"value": 2015221153856287200,
"type": "INT64"
},
"fjpFSGuidForReference": {
"value": "14102C0A-60F2-4457-AC1C-601BC628BF47-184-000000012D225C57",
"type": "STRING"
},
"fsDateSearch": {
"value": "2015221153856287158",
"type": "STRING"
},
},
"recordChangeTag": "id4w7ivn",
"created": {
"timestamp": 1439149087571,
"userRecordName": "_0d26968032e31bbc72c213037b6cb35d",
"deviceID": "A19CD995FDA3093781096AF5D818033A241D65C1BFC3D32EC6C5D6B3B4A9AA6B"
},
"modified": {
"timestamp": 1439149087571,
"userRecordName": "_0d26968032e31bbc72c213037b6cb35d",
"deviceID": "A19CD995FDA3093781096AF5D818033A241D65C1BFC3D32EC6C5D6B3B4A9AA6B"
}
}
],
"total":
}
Child Object:
{
"records": [
{
"recordName": "2015221153856287168",
"recordType": "ChildObject",
"fields": {
"District": {
"value": "002",
"type": "STRING"
},
"ZipCode": {
"value": "12345",
"type": "STRING"
},
"InspecReference": {
"value": {
"recordName": "14102C0A-60F2-4457-AC1C-601BC628BF47-184-000000012D225C57",
"action": "NONE",
"zoneID": {
"zoneName": "_defaultZone"
}
},
"type": "REFERENCE"
},
},
"recordChangeTag": "id4w7lew",
"created": {
"timestamp": 1439149090856,
"userRecordName": "_0d26968032e31bbc72c213037b6cb35d",
"deviceID": "A19CD995FDA3093781096AF5D818033A241D65C1BFC3D32EC6C5D6B3B4A9AA6B"
},
"modified": {
"timestamp": 1439149090856,
"userRecordName": "_0d26968032e31bbc72c213037b6cb35d",
"deviceID": "A19CD995FDA3093781096AF5D818033A241D65C1BFC3D32EC6C5D6B3B4A9AA6B"
}
}
],
"total": 1
}
I'm trying to write a query to directly access the CloudKit web service and return the Child Object based on the reference of the parent object.
My test JSON looks something like this:
{"query":{"recordType":"ChildObject","filterBy":{"fieldName":"InspecReference","fieldValue":{ "value" : "14102C0A-60F2-4457-AC1C-601BC628BF47-184-000000012D225C57", "type" : "string" },"comparator":"EQUALS"}},"zoneID":{"zoneName":"_defaultZone"}}
However, I'm getting the following error from CloudKit:
{"uuid":"33db91f3-b768-4a68-9056-216ecc033e9e","serverErrorCode":"BAD_REQUEST","reason":"BadRequestException:
Unexpected input"}
I'm guessing I have the Record Field Dictionary in the query wrong. However, the documentation isn't clear on what this should look like on a reference object.
You have to re-create the actual object of the reference. In this particular case, the JSON looks like this:
{
"query": {
"recordType": "ChildObject",
"filterBy": {
"fieldName": "InspecReference",
"fieldValue": {
"value": {
"recordName": "14102C0A-60F2-4457-AC1C-601BC628BF47-184-000000012D225C57",
"action": "NONE"
},
"type": "REFERENCE"
},
"comparator": "EQUALS"
}
},
"zoneID": {
"zoneName": "_defaultZone"
}
}