-
Notifications
You must be signed in to change notification settings - Fork 62
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Sparql ASK Query to implement unique constraint? #182
Comments
This looks like |
yes, i would use sh:maxCount if i needed to check if a single instance has more than one ex:email. What I'm looking to do is check all instances of ex:Person to see if any of them have the same value for ex:email. Unless there is something I am missing/not seeing? |
Right, I read that backwards, I see now. I think you could do this by treating the email value as a node---which it formally is, but linguistically I still have a hard time calling literals nodes. ex:my-email-objects-shape
a sh:NodeShape ;
# Target the *object* of the predicate. So, the Object member of the triple is the node whose shape we're constraining.
sh:targetObjectsOf ex:email ;
# Peek backwards to the subject using an inverse path.
sh:property [
a sh:PropertyShape ;
sh:maxCount 1 ;
sh:path [
sh:inversePath ex:email .
] ;
] ;
# That should do it.
. |
Thanks! Just tried this and it throws validation error when the email addresses are the same, but also throws a validation error when they are different.
|
AGH! I just realized what I did wrong. this works!! |
thanks so much for your help! now working on if I can create a composite unique. This seems to work. Does it look correct semantically?
|
It looks like I missed you'd probably meant to reply to me. I do not know what the semantics are of putting multiple Also, my recollection was one subject of
Confirming this has nothing to do with the instance data, here is the same command run against a graph with one
If you take what is piled into one Back to uniqueness-constraining: What you need to do is select the object of the predicate, and then "hop backwards". Here is your example graph showing a corrected implementation and a still-incorrect implementation, also with one more individual that is expected to not trigger an error: $ cat ex.ttl
@prefix ex: <http://example.com/> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix ex.i: <http://example.com/instance/> .
# ONTO & SHACL
ex:Person
a
owl:Class ,
sh:NodeShape
;
sh:property
[
sh:name "unique constraint" ;
rdfs:comment "This shape is NOT correct yet. No complaints raised from DATA section's ex:email usage."@en ;
sh:maxCount 1 ;
sh:path [
sh:inversePath ex:email ;
] ;
] ,
[
sh:name "unique constraint" ;
sh:maxCount 1 ;
sh:path (
ex:address
[
sh:inversePath ex:address ;
]
) ;
]
;
.
# DATA
ex.i:Person1 a ex:Person ;
ex:email "email@address.com" ;
ex:address "address" .
ex.i:Person2 a ex:Person ;
ex:email "email@address.com" ;
ex:address "address" .
ex.i:Person3 a ex:Person ;
ex:email "email2@address2.com" ;
ex:address "a different address" . Here is the shell transcript of running that - and because your
Do you see why? |
Oops, I realized I an error in my demonstration. I think the uniqueness constraint needs to include a qualified shape on the class of the thing being hopped "back" towards. Depending on whether this is intended or not, the pervasiveness of the backwards hop can be demonstrated by adding this extra individual to the graph - note that it is typeless: ex.i:Person4
ex:email "email2@address2.com" ;
ex:address "a different address" .
I'm not sure offhand how to write such a qualified shape. It sounds like a good SHACL exercise. |
@ajnelson-nist Thank you for your help fielding this issue. @tduval-unifylogic Is this issue resolved? Can it be closed now? |
Greetings again!
I am attempting to implement a unique constraint using Sparql as there is no predicate for this (that I know of ) in SHACL.
My thoughts were to use a sparql ask query. I have looked through tests/examples and cannot find an example of where an ask query is used in such a manner as I am looking to implement.
Here is what I'm attempting to use that doesn't get me the desired results.
Any suggestions are greatly appreciated!
The text was updated successfully, but these errors were encountered: