ShEx Validation - reason and appInfo are null in Result Shape Map - java

I am learning ShEx and using 'shexjava API' done by http://shexjava.lille.inria.fr/ for my project. I have schema, data graph and fixed shape map. When I validate using refine and recursive validation, I am getting ResultShapeMap but the reason and appInfo are null for NONCONFORMANT status. I do not understand why these two fields are null.
I have schema, dataGraph, shapeMap. This is code for validation.
ValidationAlgorithm vl = new RefineValidation(schema, dataGraph);
ResultShapeMap result = vl.validate(shapeMap);
Shape is,
{
"#context": "http://www.w3.org/ns/shex.jsonld",
"type": "Schema",
"shapes": [
{
"id": "http://example.com/ns#HouseShape",
"type": "Shape",
"expression": {
"type": "EachOf",
"expressions": [
{ "type": "TripleConstraint",
"predicate": "http://example.com/ns#number",
"valueExpr": { "type": "NodeConstraint",
"datatype": "http://www.w3.org/2001/XMLSchema#String"
}
},
{ "type": "TripleConstraint",
"predicate": "http://example.com/ns#size",
"valueExpr": { "type": "NodeConstraint",
"datatype": "http://www.w3.org/2001/XMLSchema#decimal"
}
}
]
}
}
]
}
Data is,
ex:House1 a ex:House ;
ex:number "11A" ;
ex:size 23 .
My Result is,
ResultShapeMap [
associations= [
ShapeAssociation [
nodeSelector=<example.com/ns#House>,
shapeSelector=<example.com/ns#HouseShape>,
status=NONCONFORMANT,
reason=null,
appInfo=null
]
]
]
I want to output the reason for not conforming. But it gives me null for that.
Could some one please help me.

The shexjava implementation currently does not support indicating a reason for failure.
This is because when a node does not satisfy a shape there may be several reasons.
If you want to learn ShEx, I would advise you to use ShapeDesigner
https://gitlab.inria.fr/jdusart/shexjapp/
which provides a graphical interface in which you can explore validation results.
In this particular case, it indicates that the validation fails because 23 is not a decimal (it's actually an integer) Screenshot of validation exploration result in ShapeDesigner
I do not know whether this is a bug, i.e. whether integrers should be considered to be also decimals in RDF.

Related

Is there a way to extract all values by some key from a list of maps using SpEL?

Let's assume there's a map corresponding to the following structure:
{
"lists": [
{
"list": [
{
"letter": "a"
},
{
"letter": "b"
}
]
},
{
"list": [
{
"letter": "c"
},
{
"letter": "d"
}
]
}
]
}
There's an easy way to get all lists using SpEL (#root['lists']) or all letters of the first list ("#root['lists'][0]['list']") or the first letter of the first list ("#root['lists'][0]['list'][0]"). Also, there's a projection mechanism which allows using construction like "#root['lists'].![#this['list']]" to convert each item of lists to a result of the projection expression.
However, given all these possibilities, I still failed to come up with an expression allowing me to extract all letters from both lists. For the example above, I'd like to get
[
{
"letter": "a"
},
{
"letter": "b"
},
{
"letter": "c"
},
{
"letter": "d"
}
]
I tried to use the projection mechanism to achieve my goal but it didn't really help. The problem I see is that every time SpEL detects a list, it applies the projection expression to each element of the list so any structure of nested lists can't be changed this way.
The problem I solve can be easily solved using JsonPath, however, I assume I could get something wrong and didn't notice a way to achieve the same result using SpEL. I would be happy to listen to any ideas.

Lambda Java - Iterate a Json Object. It looks like inside is duplicated

I have a json like this and I use forEach to go over family
{
"people": {
"family": [
{
"id": "123",
"member": [
{
"id": "11",
"salary": false
},
{
"id": "12",
"salary": false
}
]
},
{
"id": "124",
"member": [
{
"id": "11",
"salary": false
},
{
"id": "12",
"salary": false
}
]
}
]
}
}
For instance, if I set the salary in true in the first member id 123, when i go through the second element of family (id 124), salary is also in true.
If I change something in the second one id 124, the first id 123 has the same value. It looks like every family element it's the same object but not sure how I can find out that and also how to fix it.
The code is really big, but basically I'm doing something like this:
.forEach(family -> {
family.getId() // I get 123 and then 124
family.getMember().forEach(member -> {
System.out.println(member.getSalary()) // Show false for id 123 but then for id 124, show true when i would be false at this point
member.setSalary(true);
Any idea? not sure what else I can do.... Thanks
Check if objects in member collection for 123 and 124 are different, have different reference. It sounds like those objects has the same reference in those two collections. Try maybe to override equals and hashCode.
so I am assuming the corrected result should be:
false
false
false
false
this statement member.setSalary(true); is shouldn't be affected
"member" is should be in separate object it shouldn't refer to same reference (pretty weird)
can u post the full block of code?

Java - tree data structure with multiple nodes - how to search efficiently

I am searching for a implementation/data structure for some categories and child categories that i have. I am thinking to use a search tree but not sure how to begin implementation.
Let me show you what the data looks like. its acutally coming to me as a json structure from back end but it looks like this:
[
{
"id": 94,
"category_name": "New In", //this is the category category_name
"description": "",
"children": [ //this is the category children which can also be a sub-category
{
"id": 322,
"category_name": "New Studio",
"description": "Chic, sophisticated and polished with a classic edge."
},
{
"id": 365,
"category_name": "New Soho",
"description": "Fresh, eclectic, and trendy. Oozes effortless cool."
},
{
"id": 809,
"category_name": "Summer Collection",
"description": "Your ultimate summer look"
}
]
},
{
"id": 12,
"category_name": "Clothes",
"description": "",
"children": [
{
"id": 22,
"category_name": "All Clothes",
"description": ""
},
{
"id": 63,
"category_name": "Tops",
"description": "",
"children": [
{
"id": 5,
"category_name": "All Tops",
"description": ""
}
]
},
{
"id": 641,
"category_name": "Accessories",
"description": "",
"children": [
{
"id": 61,
"category_name": "All Accessories",
"description": ""
},
{
"id": 622,
"category_name": "Jewelry",
"description": "",
"children": [ // here is an example of a child that is a sub-category also
{
"id": 52,
"category_name": "All Jewelry",
"description": ""
},
{
"id": 68,
"name": "Necklaces",
"description": ""
},
{
"id": 69,
"name": "Bracelets",
"description": ""
},
]
},
]
so if i had to draw this out it would look something like this:
So i want to be able to get path to anything. So for example if i want to search for Necklaces, then i want as well as getting a necklace to get the path of : Categories/Accessories/Jewelry/Necklaces
Is there a built in data structure for this ? i am coding in java. I suppose i also need the nodes sorted in some kind of order maybe A-Z.
so far i have this:
class Node{
String label;
List<Node> children;
}
but then how to search ? and is there a better data structure ? I do not want to iterate over all the nodes during a search, is there a way to sort the tree so i dont have to do that ? How i have it now i'd have to iterate over all the children. is there a way to maybe sort alphaetically perhaps or some kind of sort that would make the lookup faster ?
You need two things for this:
In your Node object, have a reference to the parent node as well:
class Node{
String label;
List<Node> children;
Node parent;
}
Create a HashMap that maps labels to the nodes:
HashMap<String, Node> labelsToNodes;
Then searching is done with the get() method in the HashMap. You get your category list by repeatedly getting the parent nodes. Let me know if you'd like the code for this and I'll add it (I'm short on time right now).
So far I do not know any Java built-in data structure that can handle what you are looking for. There are some tree implementations on github or this thread on stackoverflow will help you.
But if I understood you right, you are also interested to have a well performing search on your tree.
Sorting the tree does not completly solve this problem, because you still have to search every single subtree. Though it could significantly improve the search performance. But as far as I know there is no out of the box data structure in Java.
Another approach that came to my mind is to use a Map with your label and a reference to the according Node. However you would need a Tree where you can go from the leaves to the root node to get the full path and you have to take care of the duplicated information. E.g. if you delete a node, you also have to delete it in the map. If you also want to traversy the tree from the root you might build a bidirectional tree.
This is how my approach would look like:
class Node {
String label;
Node parent;
}
class Tree {
HashMap<String, List<Node>> tree;
}
It is a List<Node> if you have multiple times the same label name. E.g. if you have necklaces at jewlery and summer collection
I had a project this semester for searching on trees. I used different kind of algorithms. For example, BFS or DFS it depends on what you want and how you want to move on nodes in your tree. But, I prefer IDS(Iterative deepening depth-first search). To use this algorithm you can access this links.
it is better to have father instead of children cause it works better and you will not run out of memory.
clip in Youtube to show IDS
complete teaching about IDS
There are other good algorithms if you want you can just ask me.
You need to define a State class.
class State{
String name;
State father;
}

Effective way to use must and must_not in a single search phrase?

I am new to ElasticSearch and lookig currently into must and must_not type of search criteria.
I have the following query DSL:
curl -XPOST 'localhost:9200/employee/_search?pretty' -d '
{
"query": {
"bool": {
"must": [
{ "match": { "age": "40" } }
],
"must_not": [
{ "match": { "state": "ID" } }
]
}
}
}'
Now my question is , is there any way i can optimize the above query?
Like, if i have to search for multiple must and must_not criteria, the query would become very large and difficult to manage. Is there any way i can combine both must and must_not under a single search phrase?
As far as I know you could use "should" to put several matches inside a "bool" statement (not sure why exactly it does not work with directly one "bool" statement):
Edit Actually to have several matches, without a too complex request, what is below should work normally:
{
"query": {
"bool":{
"must": [
{"match":{"age":"40"}},
{"match":{"name": "John"}}
]
, "must_not": [
{"match":{"age":"40"}},
{"match":{"name": "John"}}
]
}
}
}
Unfortunately, must and must_not cannot be combined

Reading Configuration in Java, JSON an Option?

I'm setting up a configuration file and system to process it. The current file I have is all JSON and is read using the GSON library. What I'd like to do is change part of the configuration file so I can chain rules to add more advanced logic.
For example, the configuration part would look similar to (assume it's JSON, but clearly it's not proper syntax):
Parts: {
{
{
Type: Keyword,
Keywords: "a,b,c",
UniqueOnly: true,
Threshold: 2,
}
AND
{
Type: RegEx,
Pattern: "^(abc|123)$",
UniqueOnly: true,
Threshold: 2,
}
}
OR
{
Type: Keyword,
Keywords: "abc",
Threshold: 1
}
}
The inner parts will be able to translate back to a class appropriately but between the rules I'd like to have an option for "AND" as well as "OR" with nesting. Is this something that can be achieved with ease with any JSON/GSON parsers or is it more along the lines of needing to write an entirely custom reader from scratch?
I would use valid JSON in this situation or would not use JSON at all. I have tried to do what you wnat and placed it on gist. The resulting JSON that is both serialized and deserialized looks like the following:
{
"combOperation": "OR",
"elements": [
{
"combOperation": "AND",
"elements": [
{
"regex": "^[a-zA-Z]*",
"uniqueOnly": false,
"threshold": 1
},
{
"keyWord": "BarFoo",
"uniqueOnly": false,
"threshold": 5
}
]
},
{
"keyWord": "FooBar",
"uniqueOnly": true,
"threshold": 2
}
]
}

Categories

Resources