IRI Mapping and referencing in JSON-LD - json

I am trying to design an ontology using JSON-LD but i'm having trouble getting the syntax right. I looked at https://www.w3.org/TR/json-ld but couldn't find exactly the piece of information I am looking for, which is this: How to nest IRI's in the context, and how to reference them in the body?
{
"#context":{
"#base":"http://example.com/",
"instances":"base:instances",
"animals":"base:animals",
"plants":"base:plants"
},
"#graph":[
{
"#id": "instances:1",
"#type": "Plant",
"plants:numleaves": "8",
"plants:speciesname": "sunflower"
},
{
"#id": "instances:2",
"#type": "Animal",
"animals:numlegs": "4",
"animals:speciesname": "dog",
"animals:eats": "instances:1"
}
]
}
I want the id of the first element to be http://example.com/instances#1, but when I run it through http://json-ld.org/playground/ , it's expanded form is base:instances1. How do I make it right?

It doesn't work the way you want, because you define #base and then try to use it as a prefix.
Also the hash (#) won't just magically appear. You must include it in your base URI.
To sum up you would have to change your context to:
"#context":{
"base":"http://example.com/",
"instances":"base:instances#",
"animals":"base:animals#",
"plants":"base:plants#"
}
Now instances:1 is a concatenation of http://example.com/ + instances# + 1 as you ask for.

Related

HATEOS with HAL and links to embedded ressources

I think the answer to this question is great because it explains a lot about HAL: How to handle nested resources with JSON HAL?
However it does not fully answer the question (at least for me). Assuming we have a /employees resource that returns a list of all employees. I want the employees embedded but just with some basic information (not the full employee). This is OK according to the above answer and the spec. But how would my link look like?
So what would _links look like? Lets simplify the example. Assume there is no paging:
GET /employees
{
"_links": {
"self": { "href": "/employees" },
"employees" { "href": "/employees/{id}", "templated": "true" }
},
"_embedded": {
"employees": [{
"id": "1",
"fullname": "bla bli",
"_links": { ... }
},
{
"id": "2",
"fullname": "djsjsdj",
"_links": { ... }
}]
}
}
Does the templated "emloyees" URL make sense or would this be a case where you would not use any entry in _links? And if the URL is OK: is it necessary that the template parameter (here "id" does match the attribute in the embedded employee objects?
My heuristic is to consider the analogs in HTML - if it's OK for a web page, then it will also be OK for HAL.
"employees" { "href": "/employees/{id}", "templated": "true" }
What's the HTML analog? It's a form with a GET action. Can we have a form with a get action on a web page that also has digests of the information that will be reached via the form? Of course. So it must be fine here.
is it necessary that the template parameter (here "id") does match the attribute in the embedded employee objects?
I don't think it's necessary (the machines don't really care), but it's going to make life easier for the humans, and that alone has value.
Imagine, if you will, reading the documentation of a schema, and discovering that the same semantic concept (an identifier for an employee) has two different names with unrelated spellings. I would guess that would (a) introduce avoidable errors in the documentation when authors get confused about which spelling context they are in and (b) that's the sort of inconsistency that would make me suspicious of the quality of the specification as a whole.
But it's not impossible to have tradeoffs, and other benefits that outweigh these liabilities.

JSON path evaluation

given this node in a json response:
{
"name": "RFM912Feilkode",
"valueCodeableConcept": {
"coding": [
{
"system": "http://xxx/error-code",
"code": "0"
}
],
"text": "OK"
}
I want to verify that the text "OK" is present in Gatling using Scala syntax.
Something (pseudo code ish):
.check(jsonPath("$..valueCodeableConcept.text").is("OK"))
but this does not work. Any tips on how to "hit" the OK value and check if it exists?
Your json isn't valid. Missing curly bracket.
I tried this and all works fine:
.check(jsonPath("$.valueCodeableConcept.text").is("OK"))
If you want to extract some json based on other elements in the json (what you seem to be getting at in the comments on other answers), then you can use filters in the jsonPath like
$.[?(#.name=="RFM912Feilkode")].valueCodeableConcept.text
which will get you the text element from valueCodeableConcept where the associated name is RFM912Feilkode

Removing an item from a collection in a HATEOAS way

I am working on a project whose client uses REST/HATEOAS to get and modify data.
Here is a part of the class diagram: class diagram.
A hal+json HATEOAS response of the request /group/12345 would look like:
{
"id": "12345",
"_links": {
"self": {
"href": "/group/12345"
},
"roles": {
"href": "/group/12345/roles"
}
}
}
To remove a role from this group I could simply execute a DELETE on the specific role. (because every role has to be in exactly one group and moving a role to another group shouldn't be allowed).
So I would add a link with the rel "drop" to the role. Therefore the client knows if or rather when a DELETE request is allowed:
{
"id": "67890",
"_links": {
"self": {
"href": "/roles/67890"
},
"users": {
"href": "/roles/67890/users"
},
"drop": {
"href": "/roles/67890"
}
}
}
So to delete a user the client looks for the drop link. If no link is found, the delete is not allowed. Otherwise it executes a DELETE request on the found link.
But what should I do if I want to remove a user from a role?
I cannot simply delete the user. The role -> user relation is not an aggregation.
How can I tell the client if removing a user from a role is allowed?
To remove a user from role I would use DELETE /groups/12345/roles/67890/users/ABC. And to delete the user I would use DELETE /users/ABC.
So where should I put the "remove user from role" link?
Thank you in advance :)
Links typically have three parts
A context identifier
a link relation type
a target identifier
Frequently, the context identifier is implied by the... umm... context, rather than being made explicit.
From what I can see, hal+json doesn't have a mechanism for explicitly specifying the context identifier, which would mean that you need to rely upon the implicit approach.
That suggests that if you want to be communicating about removing a user from a role, then you need a context that implies the right identifier.
You would normally do this in one of two ways
have a chain of links that leads to a representation of the user in that role, and include the drop role link relation in the list of links
embed a representation of the user in some other representation, and include the drop role link within that embedded resource.
For example, you might have a representation of /roles/67890/users that looks something like
_links: {
self: {
href: /roles/67890/users
}
}
_embedded: {
users: [ {
_links: {
self: /users/ABC
/role/remove : /groups/12345/roles/67890/users/ABC
}
} ,
... ]
}

Mongo DB query of complex json structure

Say I have a json structure like so:
{
"A":{
"name":"dog",
"foo":"bar",
"array":[
{"name":"one"},
{"name":"two"}
]
},
"B":{
"name":"cat",
"foo":"bar",
"array":[
{"name":"one"},
{"name":"three"}
]
}
}
I want to be able to do two things.
1: Query for any "name":* within "A.array".
2: Query for any "name":"one" within "*.array".
That is, any object within a specific document's array, and any specific object within any document's array.
I hope I have used proper terminology here, I am just starting to familiarize myself with a lot of these concepts. I have tried searching for an answer but am having trouble finding something like my case.
Thanks.
EDIT:
Since I still haven't really made progress towards this, I'll just explain what I'm trying to do: I want to use the "AllSets" dataset (after I trim it down below 16mb) available on mtgjson.com. I am having problems getting mongo to play nicely though.
In an effort to try and learn what's going on, I have downloaded one set: http://mtgjson.com/json/OGW.json.
Here is a photo of its structure laid out:
I am unable to even get mongo to return an object from within the cards array using:
"find({cards: {$elemMatch: {name:"Deceiver of Form"}}})"
"find({"cards.name":"Deceiver of Form"})"
When I run either of the commands above it just returns the entire document to me.
You could use the positional projection $ operator to limit the contents of an array. For example, if you have a single document like below:
{
"block": "Battle for Zendikar",
"booster": "...",
"translations": "...",
"cards": [
{
"name": "Deceiver of Form",
"power": "8"
},
{
"name": "Eldrazi Mimic",
"power": "2"
},
{
"name": "Kozilek, the Great Distortion",
"power": "12"
}
]
}
You can query for a card name matching "Deceiver of Form", and limit fields to return only the matching array card element(s) using:
> db.collection.find({"cards.name":"Deceiver of Form"}, {"cards.$":1})
{
"_id": ObjectId("..."),
"cards": [
{
"name": "Deceiver of Form",
"power": "8"
}
]
}
Having said the above, I think you should re-consider your data model. MongoDB is a document-oriented database. A record in MongoDB is a document, so having a single record in a database does not bring out the potential of the database i.e. similar to storing all data in a single row in a table.
You should try storing the 'cards' into a collection instead. Where each document is a single card, (depending on your use case) you could add a reference to another collection containing the deck information. i.e: block, type, releaseDate, etc. For example:
// a document in cards collection:
{
"name": "Deceiver of Form",
"power": "8",
"deck_id": 1
}
// a document in decks collection:
{
"deck_id": 1,
"releaseDate": "2016-01-22",
"type": "expansion"
}
For different types of data model designs and examples, please see Data Model Design.

It is possible to generate a JSON schema for dynamic attributes

The problem is that in my app we have a data structure like this:
{
"adults": {
"jagger_mick_dateOfBirth": {
"name": "Mick"
"lastName": "Jagger",
"more atributes": ""
},
"jolie_angelina_dateOfBirth": : {
"name": "Angelina"
"lastName": "Jolie",
"more atributes": ""
}
},
"children": {
"osbourne_ozzy_dateOfBirth": : {
"name": "Ozzy"
"lastName": "Osbourne",
"more atributes": ""
}
}
}
As you can see, for each Adult & Children, we use a dynamic attribute to identify each object. BUT inside is the same object.
Right now I am in the process to generate JSON Schemas (v4) for this data structure.
My problem is i cannot find a property to evaluate dynamic attributes, althought the object is the same, just the key is different.
I know that it is bad coding, but it is possible to generate a JSON Schema (v4) to validate a dynamic attribute (key) ?
Thanks in advance.
P.D.
If you are wondering why we use this approach, is because we can access directly to the object, instead of search for it.
If your dynamic object attributes can be described with a regular expression, you can use patternProperties keyword.