You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@jena.apache.org by Paul Houle <on...@gmail.com> on 2016/01/06 17:50:58 UTC

CONSTRUCT + Blank nodes

This is a simple scenario,  I can accomplish the specific thing I am trying
to di by other means,  but if I can get this to work it leads to a strategy
inspired by SPIN,  I'm showing it though because it is a simple and clear
example.

I have two graphs,

G1:

[] a :DatasetArtifact ;
   :name e:tdb ;
   :path "/lei/testCase/a" .


G2:

@prefix : <http://rdf.ontology2.com/mogrifier1/>

:DatasetArtifact :implementation
<java:com.ontology2.rdf.mogrifier.MemoryDatasetFactory> .
:GraphArtifact :implementation
<java:com.ontology2.rdf.mogrifier.GraphInsertFactory> .
:LuceneArtifact :implementation
<java:com.ontology2.rdf.mogrifier.LuceneFactory> .

Now I can query the union of G1 and G2 and I want to make the graph
above look like

[] a :DatasetArtifact ;
   :name e:tdb ;   :implementation
<java:com.ontology2.rdf.mogrifier.MemoryDatasetFactory> .
   :path "/lei/testCase/a" .

I can do the following CONSTRUCT query

prefix : <http://rdf.ontology2.com/mogrifier1/>

CONSTRUCT {
   ?artifact :implementation ?class
} WHERE {
   ?artifact a ?type  .
   ?type :implemenation ?class .
}

And this will do the right thing if the "root" node is not a bnode but
if it is a bnode it creates an output like

G3

[ :implementation <java:com.ontology2.rdf.mogrifier.MemoryDatasetFactory> ]

and this bnode is not the same bnode as the original bnode so when I
take the model I get from execConstruct and append G3 to G1 I don't
get the desired result.  If I try to have the construct put results
back into the original model I get a ConcurrentModificationException
so I can't do it that way.

Operations like this where you pull out a bnode reference and then add
some properties to it are easy to do with the Model interface,  but
not officially supported in SPARQL.

I know that Jena and some other stores support ways to get bnode
identifiers out of SPARQL queries so it seems to me that has to be
some trick,  even if it is a touch evil,  that makes it possible to do
something like the above.  I could skolemize the roots,  but I might
have 2nd level or 3rd level bnodes in some records.  There are a
number of other ways I could merge in the :implementation that would
work just fine in this case,  but I like the simplicity of this
solution,  the ability to do much more complex things with more
complex queries and the composibility of this approach.

Is this practical to attain?




-- 
Paul Houle

*Applying Schemas for Natural Language Processing, Distributed Systems,
Classification and Text Mining and Data Lakes*

(607) 539 6254    paul.houle on Skype   ontology2@gmail.com

:BaseKB -- Query Freebase Data With SPARQL
http://basekb.com/gold/

Legal Entity Identifier Lookup
https://legalentityidentifier.info/lei/lookup/
<http://legalentityidentifier.info/lei/lookup/>

Join our Data Lakes group on LinkedIn
https://www.linkedin.com/grp/home?gid=8267275

Re: CONSTRUCT + Blank nodes

Posted by Andy Seaborne <an...@apache.org>.
To make a connection here ...

SHACL [*] seems to have a similar issue; it needs to apply shape 
constraints to resources which are potentially bnode-subject structures.

[*]
http://www.w3.org/TR/shacl/

On 06/01/16 16:50, Paul Houle wrote:
> This is a simple scenario,  I can accomplish the specific thing I am trying
> to di by other means,  but if I can get this to work it leads to a strategy
> inspired by SPIN,  I'm showing it though because it is a simple and clear
> example.
>
> I have two graphs,
>
> G1:
>
> [] a :DatasetArtifact ;
>     :name e:tdb ;
>     :path "/lei/testCase/a" .
>
>
> G2:
>
> @prefix : <http://rdf.ontology2.com/mogrifier1/>
>
> :DatasetArtifact :implementation
> <java:com.ontology2.rdf.mogrifier.MemoryDatasetFactory> .
> :GraphArtifact :implementation
> <java:com.ontology2.rdf.mogrifier.GraphInsertFactory> .
> :LuceneArtifact :implementation
> <java:com.ontology2.rdf.mogrifier.LuceneFactory> .
>
> Now I can query the union of G1 and G2 and I want to make the graph
> above look like
>
> [] a :DatasetArtifact ;
>     :name e:tdb ;   :implementation
> <java:com.ontology2.rdf.mogrifier.MemoryDatasetFactory> .
>     :path "/lei/testCase/a" .
>
> I can do the following CONSTRUCT query
>
> prefix : <http://rdf.ontology2.com/mogrifier1/>
>
> CONSTRUCT {
>     ?artifact :implementation ?class
> } WHERE {
>     ?artifact a ?type  .
>     ?type :implemenation ?class .
> }
>
> And this will do the right thing if the "root" node is not a bnode but
> if it is a bnode it creates an output like
>
> G3
>
> [ :implementation <java:com.ontology2.rdf.mogrifier.MemoryDatasetFactory> ]

To be clear here:

The construct really does use the same bnode as the query part found. 
The problem is RDF serialization, not CONSTRUCT.  if run locally that 
will work fine.

> and this bnode is not the same bnode as the original bnode so when I
> take the model I get from execConstruct and append G3 to G1 I don't
> get the desired result.  If I try to have the construct put results
> back into the original model I get a ConcurrentModificationException
> so I can't do it that way.

Could you provide a complete minimal example?

Or if you are iterating over the triples returned with 
"execConstructTriples", not using the model returned by "execConstruct" 
then either buffered updates or "don't do that".

If you want to reinsert them , use SPARQL Update ... which will all 
execute in the same bnode context.

>
> Operations like this where you pull out a bnode reference and then add
> some properties to it are easy to do with the Model interface,  but
> not officially supported in SPARQL.
>
> I know that Jena and some other stores support ways to get bnode
> identifiers out of SPARQL queries so it seems to me that has to be
> some trick,  even if it is a touch evil,  that makes it possible to do
> something like the above.  I could skolemize the roots,  but I might
> have 2nd level or 3rd level bnodes in some records.  There are a
> number of other ways I could merge in the :implementation that would
> work just fine in this case,  but I like the simplicity of this
> solution,  the ability to do much more complex things with more
> complex queries and the composibility of this approach.
>
> Is this practical to attain?

SPARQL Update.

>
>
>
>

	Andy

Re: CONSTRUCT + Blank nodes

Posted by Martynas Jusevičius <ma...@graphity.org>.
Blank nodes are local to the graph. Why don't you relabel them as URIs
and the problem should go away? (if I understood your use case
correctly)

On Wed, Jan 6, 2016 at 5:50 PM, Paul Houle <on...@gmail.com> wrote:
> This is a simple scenario,  I can accomplish the specific thing I am trying
> to di by other means,  but if I can get this to work it leads to a strategy
> inspired by SPIN,  I'm showing it though because it is a simple and clear
> example.
>
> I have two graphs,
>
> G1:
>
> [] a :DatasetArtifact ;
>    :name e:tdb ;
>    :path "/lei/testCase/a" .
>
>
> G2:
>
> @prefix : <http://rdf.ontology2.com/mogrifier1/>
>
> :DatasetArtifact :implementation
> <java:com.ontology2.rdf.mogrifier.MemoryDatasetFactory> .
> :GraphArtifact :implementation
> <java:com.ontology2.rdf.mogrifier.GraphInsertFactory> .
> :LuceneArtifact :implementation
> <java:com.ontology2.rdf.mogrifier.LuceneFactory> .
>
> Now I can query the union of G1 and G2 and I want to make the graph
> above look like
>
> [] a :DatasetArtifact ;
>    :name e:tdb ;   :implementation
> <java:com.ontology2.rdf.mogrifier.MemoryDatasetFactory> .
>    :path "/lei/testCase/a" .
>
> I can do the following CONSTRUCT query
>
> prefix : <http://rdf.ontology2.com/mogrifier1/>
>
> CONSTRUCT {
>    ?artifact :implementation ?class
> } WHERE {
>    ?artifact a ?type  .
>    ?type :implemenation ?class .
> }
>
> And this will do the right thing if the "root" node is not a bnode but
> if it is a bnode it creates an output like
>
> G3
>
> [ :implementation <java:com.ontology2.rdf.mogrifier.MemoryDatasetFactory> ]
>
> and this bnode is not the same bnode as the original bnode so when I
> take the model I get from execConstruct and append G3 to G1 I don't
> get the desired result.  If I try to have the construct put results
> back into the original model I get a ConcurrentModificationException
> so I can't do it that way.
>
> Operations like this where you pull out a bnode reference and then add
> some properties to it are easy to do with the Model interface,  but
> not officially supported in SPARQL.
>
> I know that Jena and some other stores support ways to get bnode
> identifiers out of SPARQL queries so it seems to me that has to be
> some trick,  even if it is a touch evil,  that makes it possible to do
> something like the above.  I could skolemize the roots,  but I might
> have 2nd level or 3rd level bnodes in some records.  There are a
> number of other ways I could merge in the :implementation that would
> work just fine in this case,  but I like the simplicity of this
> solution,  the ability to do much more complex things with more
> complex queries and the composibility of this approach.
>
> Is this practical to attain?
>
>
>
>
> --
> Paul Houle
>
> *Applying Schemas for Natural Language Processing, Distributed Systems,
> Classification and Text Mining and Data Lakes*
>
> (607) 539 6254    paul.houle on Skype   ontology2@gmail.com
>
> :BaseKB -- Query Freebase Data With SPARQL
> http://basekb.com/gold/
>
> Legal Entity Identifier Lookup
> https://legalentityidentifier.info/lei/lookup/
> <http://legalentityidentifier.info/lei/lookup/>
>
> Join our Data Lakes group on LinkedIn
> https://www.linkedin.com/grp/home?gid=8267275