How do I set up my json schema structure - jsonschema

I'm trying to figure out how a json schema should be implemented (as standardized as possible).
I have noticed that if I define a schema for a form using the v4 draft, I cannot voice the requirements my project has. So I created a schema that uses the v4 schema ("$schema": "http://json-schema.org/draft-04/schema#"), and gave it a custom id for the project, lets call it projectschema#. This schema validates, so all is good standard-wise. I have added two values to the type enum.
I then use this schema as $schema for another schema that describes form properties and validations, the formschema#. This schema too validates, this time against the projectschema#.
Now, as documented on www.json-schema.org, there's also a hyper-schema which allows the definition of links. Useful, as I can define where to POST the form to, or even where to get valueSets to use in the form (i.e. a rest service to get a list of user titles).
However, the v4 schema itself does not support links. I see how the v4 hyper-schema draft does support links, and is referencing the v4 schema draft, but I cannot figure out how to implement the hyper-schema, which probably means I'm missing some fundamental part of the 'how to use and implement json schema' knowledge.
I found the following on http://json-schema.org/latest/json-schema-hypermedia.html:
JSON Schema is a JSON based format for defining the structure of JSON data. This document specifies hyperlink- and hypermedia-related keywords of JSON Schema.
The term JSON Hyper-Schema is used to refer to a JSON Schema that uses these keywords.
If the draft hyper-schema uses the draft schema keywords, then why is the 'links' keyword nowhere to be found in the schema?
Is my (or any) custom schema actually a hyper schema? And if so, is anything that implements a (custom or draft) json schema called a hyper schema?
I could fire off a hundred questions. Main question: what is the relation between a Schema and a Hyper Schema, and how should I implement a schema for a form that needs more types than defined in the v4 draft?

Sorry for the length of this answer. Hopefully it's helpful.
I too struggled to understand how to validate a particular link in Hyper-Schema so I implemented each link as a base JSON Schema then tied each link together with a Hyper-Schema.
Definitions (definitions.json):
{
"$schema" : "http://json-schema.org/schema#",
"definitions" : {
"id" : {
"type" : "integer",
"minimum" : 1,
"exclusiveMinimum" : false
},
"foreign_key_id" : {
"$ref" : "#/definitions/id"
},
"season_name" : {
"type" : "string",
"minLength" : 1,
"maxLength" : 1,
"pattern" : "^[A-T]{1,1}$"
},
"currency" : {
"type" : "integer"
},
"shares" : {
"type" : "integer"
},
"username" : {
"type" : "string",
"minLength" : 1,
"maxLength" : 19,
"pattern" : "^[^ ]{1,19}$"
},
"name" : {
"type" : "string",
"minLength" : 1,
"maxLength" : 64,
"pattern" : "^[A-Za-z0-9][A-Za-z0-9_\\- ]*$"
},
"email" : {
"type" : "string",
"format" : "email"
},
"timestamp" : {
"type" : "string",
"format" : "date-time"
}
}
}
Base object schema:
{
"$schema" : "http://json-schema.org/schema#",
"type" : "object",
"properties" : {
"id" : { "$ref" : "definitions.json#/definitions/id" },
"season_name" : { "$ref" : "definitions.json#/definitions/season_name" },
"user_id" : { "$ref" : "definitions.json#/definitions/foreign_key_id" },
"coins" : { "$ref" : "definitions.json#/definitions/currency" },
"bonus_coins" : { "$ref" : "definitions.json#/definitions/currency" },
"created_at" : { "$ref" : "definitions.json#/definitions/timestamp" },
"updated_at" : { "$ref" : "definitions.json#/definitions/timestamp" }
},
"required" : [
"id",
"season_name",
"user_id",
"coins",
"bonus_coins",
"created_at",
"updated_at"
],
"additionalProperties" : false
}
POST schema (account_request_post.json):
{
"$schema" : "http://json-schema.org/schema#",
"type" : "object",
"properties" : {
"season_name" : { "$ref" : "definitions.json#/definitions/season_name" },
"user_id" : { "$ref" : "definitions.json#/definitions/foreign_key_id" }
},
"required" : [
"season_name",
"user_id"
],
"additionalProperties" : false
}
Hyper Schema:
{
"$schema" : "http://json-schema.org/schema#",
"type" : "object",
"links" : [
{
"description" : "Create a new account.",
"href" : "accounts",
"method" : "POST",
"rel" : "create",
"title" : "Create",
"schema" : { "$ref" : "account_request_post.json#" }
},
{
"description" : "List accounts.",
"href" : "accounts",
"method" : "GET",
"rel" : "index",
"title" : "List"
}
]
}

Json hyper-schema is a subset of Json-schema standard dedicated to hyperlink and hypermedia keywords and rules.
The "links" keyword is defined in the hyper-schema section of the draft. Indeed it is a part of json-schema (despite it is defined in a special draft section)
If your are defining an API interface, it is likely you want to use hyper-schema. If you are just defining validation contracts, plain Json-schema keywords are enough.

Related

Problem requesting additional fields in REST2 api

I am using the RT::Extension::REST2 api (https://metacpan.org/pod/RT::Extension::REST2) for a project and i am having a problem requesting additional fields in some requests.
I need to make a TicketSQL query and for performance reasons i am trying to obtain all the information of a ticket with something like /REST/2.0/ticket/8?fields=Requestor and i get something like
"Requestor": [
{
"_url" : "http://<>/REST/2.0/user/example#example.com",
"id" : "example#example.com",
"type" : "user"
},
{
"_url" : "http://<>/REST/2.0/user/example#example.com",
"id" : "example#example.com",
"type" : "user"
}
]
Notice it is a List of dictionaries, so when i try to do /REST/2.0/ticket/8?fields[Requestor]=Name the field Name does not appear on the dictionaries inside the list.
So i am trying to get something like this:
"Requestor": [
{
"_url" : "http://<>/REST/2.0/user/example#example.com",
"id" : "example#example.com",
"type" : "user",
"Name" : "user20",
},
{
"_url" : "http://<>/REST/2.0/user/example#example.com",
"id" : "example#example.com",
"type" : "user",
"Name" : "user20",
}
]
Is there any way i can do this ?
Thank you for your help!

Create Custom field in Salesforce using Tooling API

I am trying to create custom field using Tooling API in Salesforce. First to check Tooling API, I tried using workbench but it is showing following error:
JSON Parser Error:
message: Cannot deserialize instance of complexvalue from VALUE_STRING value text or request may be missing a required field at [line:5, column:25]
errorCode: JSON_PARSER_ERROR
Following is the JSON body I am using:
{
"DeveloperName" : "CusField",
"Metadata":
{
"type" : "text",
"description" : "test",
"inlineHelpText" : "testhelp",
"label" : "cus Field",
"required" : false,
"precision" : null,
"length" : 255,
"unique" : false,
"externalId" : false,
"trackHistory" : false
},
"TableEnumOrId" : "Account",
"ManageableState" : "installed"
}
Please let me know what is wrong with body?
Thanks in Advance.
There are a few things wrong with the body.
Remove ManageableState
Do not include DeveloperName and TableEnumOrId, instead, use FullName as shown below
Capitalize the field type Text
Here's a working post body:
{
"FullName" : "Account.CusField__c",
"Metadata": {
"type" : "Text",
"description" : "test",
"inlineHelpText" : "testhelp",
"label" : "cus Field",
"required" : false,
"precision" : null,
"length" : 255,
"unique" : false,
"externalId" : false,
"trackHistory" : false
}
}

AvroTypeException when reading from internal Hive Table with nested Structs

I work on a Azure HDInsight cluster with version 3.6. It uses Hortonworks HDP 2.6, which comes with Hive 2.1.0 (on Tez 0.8.4).
I have some internal Hive tables with nested struct fields stored in Avro format. Here is one example CREATE statement:
CREATE TABLE my_example_table(
some_field STRING,
some_other_field STRING,
some_struct struct<field1: BIGINT, inner_struct struct<field2: STRING, field3: STRING>>)
PARTITIONED BY (year INT, month INT)
STORED AS AVRO;
I populate these tables with from an external table which also is stored as avro, like this:
INSERT INTO TABLE my_example_table
PARTITION (year, month)
SELECT ....
FROM my_external_table;
When I want to query the internal tables I got the following error: Failed with exception java.io.IOException:org.apache.avro.AvroTypeException: Found core.record_0, expecting union
I extracted the avro schema from one of these internal tables with the Avro tools and recognized that Hive creates union types from the structs I defined:
{
"type" : "record",
"name" : "my_example_table",
"namespace" : "my_namespace",
"fields" : [ {
"name" : "some_field",
"type" : [ "null", "string" ],
"default" : null
}, {
"name" : "some_other_field",
"type" : [ "null", "string" ],
"default" : null
}, {
"name" : "my_struct",
"type" : [ "null", {
"type" : "record",
"name" : "record_0",
"namespace" : "",
"doc" : "struct<field1: BIGINT, struct<field2: STRING, field3: STRING>>",
"fields" : [ {
"name" : "field1",
"type" : [ "null", "long" ],
"doc" : "bigint",
"default" : null
}, {
"name" : "inner_struct",
"type" : [ "null", {
"type" : "record",
"name" : "record_2",
"namespace" : "",
"doc" : "struct<field2: STRING, field3: STRING>",
"fields" : [ {
"name" : "field2",
"type" : [ "null", "string" ],
"doc" : "bigint",
"default" : null
}, {
"name" : "field2",
"type" : [ "null", "long" ],
"doc" : "bigint",
"default" : null
}]
}
]}
]}
]}
}
Whats going wrong here? I'm pretty sure exactly this worked some days ago, so I conjectured that Microsoft switched to another patch version of HDP for HDInsight clusters which has another Avro or Hive version, but I haven't found any indications to that.
I found this: https://issues.apache.org/jira/browse/HIVE-15316 which seems to be pretty similar problem (on the same Hive version).
Does anybody know whats going wrong here and what I could do to fix this problem or as a workaround?

ElasticSearch for Attribute(Key) value data set

I am using Elasticsearch with Haystacksearch and Django and want to search the follow structure:
{
{
"title": "book1",
"category" : ["Cat_1", "Cat_2"],
"key_values" :
[
{
"key_name" : "key_1",
"value" : "sample_value_1"
},
{
"key_name" : "key_2",
"value" : "sample_value_12"
}
]
},
{
"title": "book2",
"category" : ["Cat_3", "Cat_2"],
"key_values" :
[
{
"key_name" : "key_1",
"value" : "sample_value_1"
},
{
"key_name" : "key_3",
"value" : "sample_value_6"
},
{
"key_name" : "key_4",
"value" : "sample_value_5"
}
]
}
}
Right now I have set up an index model using Haystack with a "text" that put all the data together and runs a full text search! In my opinion this is not the a well established search 'cause I am not using my data set structure and hence this is some kind odd.
As an example if for an object I have a key-value
{
"key_name": "key_1",
"value": "sample_value_1"
}
and for another object I have
{
"key_name": "key_2",
"value": "sample_value_1"
}
and we it gets a query like "Key_1 sample_value_1" comes I get a thoroughly mixed result of objects who have these words in their fields rather than using their structures.
P.S. I am totally new to ElasticSearch and better to say new to the search technologies and challenges. I have searched the web and SO button didn't find anything satisfying. Please let me know if there is something wrong with my thoughts and expectations from these search engines and if there is SO duplicate question! And also if there is a better approach to design a database for this kind of search
Read the es docs on nested mappings and do something like this:
"book_type" : {
"properties" : {
// title, cat mappings
"key_values" : {
"type" : "nested"
"properties": {
"key_name": {
"type": "string", "index": "not_analyzed"
},
"value": {
"type": "string"
}
}
}
}
}
Then query using a nested query
"nested" : {
"path" : "key_values",
"query" : {
"bool" : {
"must" : [
{
"term" : {"key_values.key_name" : "key_1"}
},
{
"match" : {"key_values.value" : "sample_value_1"}
}
]
}
}
}

Custom score in Elastic Search

I have an index, where each document represents a class, with list of students and a list of teachers.
Here is the mapping:
{
"properties" : {
"students" : {
"include_in_root" : 1,
"type" : "nested",
"properties" : {
"name" : {
"first" : "text",
"last" : "text",
},
},
"email" : { "type" : "string", "index" : "not_analyzed" },
},
"teachers" : {
"include_in_root" : 0,
"include_in_all" : 0,
"type" : "nested",
"properties" : {
"name" : {
"title" : { "type" : "string", "index" : "not_analyzed" },
"first" : "text",
"last" : "text",
},
},
},
},
}
I would like to influence Elastic Search score function, such that it will give higher score to documents with matched techers.
For example, if I have search for "Smith", I would like the documents with teacher Smith be with higher score than documents with students Smith.
Does anyone knows how it should be done in Elastic Search?
In other words, how can I return the results ordered by some logic?
Thanks in advance!
Answered here:
https://groups.google.com/forum/?fromgroups#!search/%22Use$20a$20bool$20query$20to$20run$20two$20nested$20queries%22/elasticsearch/XTAb7eHcbqI/UgnKDh7ou48J