I am currently writing some code in Java, using Jena and TDB -- on a Windows 7.
I want to be able to load a (large) .trig file into TDB Dataset so that querying is a bit faster. The code that I currently have is:
Dataset dataset = TDBFactory.createDataset(directoryPath);
Model tdb = dataset.getDefaultModel();
RDFDataMgr.read(tdb, inputFilePath);
try {
String theQuery = readFile(testQueryPath, Charset.defaultCharset());
Query query = QueryFactory.create(theQuery);
QueryExecution qe = QueryExecutionFactory.create(query, dataset);
com.hp.hpl.jena.query.ResultSet results = qe.execSelect();
// Output query results
ResultSetFormatter.out(System.out, results, query);
qe.close();
} catch (IOException e) {
e.printStackTrace();
}
I also tried:
FileManager.get().readModel( tdb, inputFilePath);
instead of:
RDFDataMgr.read(tdb, inputFilePath);
I get the following warning:
2014-06-13 13:02:26 WARN riot:77 - Only triples or default graph data expected : named graph data ignored
The SPARQL queries I ran are:
PREFIX xsd: http://www.w3.org/2001/XMLSchema#
PREFIX dc: http://purl.org/dc/elements/1.1/
PREFIX : <.>
SELECT *
{
{ ?s ?p ?o } UNION { GRAPH ?g { ?s ?p ?o } }
}
and also the same one but without the UNION and GRAPH things.
The queries return nothing.
Does anyone see an apparent problem or know how to load .trig files into TDB?
You just read into the dataset:
RDFDataMgr.read(dataset, inputFilePath);
Inside write transaction would be better else call TDB.sync(dataset) before you exit.
You code loads it every run. If the file is really big, use tdbloader, the bulk loader, before running the query program.
Related
I'm attempting to get a simple app working with Micronaut 1.3.5 and Neo4J 4.0.0. I'm using the io.micronaut.configuration:micronaut-neo4j-bolt:2.0.0 driver. I have code like this:
public Stream<Map<String, Object>> findAll() {
try (Session s = driver.session()) {
String stmt = "MATCH (n:Product) RETURN n";
return s.readTransaction(tx -> tx.run(stmt)).list(r -> r.asMap()).stream();
}
}
And I'm getting the following exception:
result has already been consumed or the query runner where the result is created has already been closed.
org.neo4j.driver.exceptions.ResultConsumedException: Cannot access records on this result any more as the result has already been consumed or the query runner where the result is created has already been closed.
I've done some googling and found a few things that would suggest this is normal behavior, but nothing that discusses the actual solution. I'm assuming it has something to do with the async nature of the driver/session.
The way that would work is,
Stream<Map<String, Object>> stream = s.readTransaction(tx -> {
Result result = tx.run(stmt);
return result.list(r -> r.asMap()).stream();
});
The results need to be processed within the readTransaction
There are bunch of examples at https://github.com/neo4j/neo4j-java-driver/tree/4.1/examples/src/main/java/org/neo4j/docs/driver which you may find useful
I generally keep my ontologies in two different files.
First ontology file contains the classes, subclasses, data properties and object properties.
The second file containing all the individuals and relationships between the individuals.
So, I need to merge these two files in order to have a complete model. I wonder how this could be achieved using owlapi?
In Jena, I do this as follows:
OntModel model = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM,
null);
try {
model.read(new FileInputStream(MyOntologyFile), "...");
model.read(new FileInputStream(MyOntologyWithIndividualsFile), "...");
} catch (Exception e) {
log.error("Loading Model failed:" + e);
}
In the similar fashion when I tried to load my ontology files using owlapi, I get error:
OWLOntologyManager manager = OWLManager.createOWLOntologyManager();
OWLObjectRenderer renderer = new DLSyntaxObjectRenderer();
File file = new File(MyOntologyFile);
File fileIndividuals = new File(MyOntologyWithIndividualsFile);
OWLOntology localOntology = null;
// Now load the local copy
try {
localOntology = manager.loadOntologyFromOntologyDocument(file);
localOntology = manager
.loadOntologyFromOntologyDocument(fileIndividuals);
} catch (OWLOntologyCreationException ex) {
ex.printStackTrace();
}
Error:
org.semanticweb.owlapi.model.OWLOntologyAlreadyExistsException: Ontology already exists. OntologyID(OntologyIRI(<http://www.semanticweb.org/lp4220/ontologies/2014/4/untitled-ontology-35>))
at uk.ac.manchester.cs.owl.owlapi.OWLOntologyManagerImpl.loadOntology(OWLOntologyManagerImpl.java:880)
at uk.ac.manchester.cs.owl.owlapi.OWLOntologyManagerImpl.loadOntologyFromOntologyDocument(OWLOntologyManagerImpl.java:806)
at uk.ac.manchester.cs.owl.owlapi.OWLOntologyManagerImpl.loadOntologyFromOntologyDocument(OWLOntologyManagerImpl.java:821)
Update:
As it turns out, merging of ontologies is only possible with those having different IRI's, and hence I presume it is not acceptable to divide an ontology into two with the same IRI. A solution for this (as commented by Joshua) may be to read all individuals and axioms from one ontology and then add them to an already loaded ontology.
For ontologies with distinct IRI's merging can be done as follows (example courtesy Ignazio's OWLED 2011 slides - slide no. 27):
OWLOntologyManager m = create();
OWLOntology o1 = m.loadOntology(pizza_iri);
OWLOntology o2 = m.loadOntology(example_iri);
// Create our ontology merger
OWLOntologyMerger merger = new OWLOntologyMerger(m);
// Merge all of the loaded ontologies, specifying an IRI for the
new ontology
IRI mergedOntologyIRI =
IRI.create(
"http://www.semanticweb.com/mymergedont"
);
OWLOntology merged = merger.createMergedOntology(m,
mergedOntologyIRI);
assertTrue(merged.getAxiomCount() > o1.getAxiomCount());
assertTrue(merged.getAxiomCount() > o2.getAxiomCount());
Your problem is not having the same iri in the data but ontologies with the same iris loaded in the same manager. Load the ontologies in separate managers and add all the axioms from one to the other, that will give you a merged ontology.
In general, you do not make "Individuals and Relationships" an Ontology, unless they require for classifications - say to define Class "American Company" you need an Individual "US". Otherwise, that other part is should be your RDF triples that refer to the Ontology.
I have an OWL ontology file as RDF and want to store my data in a TDB and want to use reasoning. Actually this sounds simple so far :)
But here is the point where I'm confuesd:
I created a TDB an stored via SPARQL some statements. Then I tried to load the TDB via a model and OWL reasoner:
OntModelSpec ontModelSpec = OntModelSpec.OWL_MEM;
Reasoner reasoner = ReasonerRegistry.getOWLReasoner();
ontModelSpec.setReasoner(reasoner);
Model schemaModel = FileManager.get().loadModel("D:/Users/jim/Desktop/ontology/schema.rdf");
OntModel schema = ModelFactory.createOntologyModel( ontModelSpec, schemaModel);
Location location = new Location("D:/Users/jim/Desktop/jena-fuseki-0.2.5/DB");
Dataset dataset = TDBFactory.createDataset(location);
Model model = dataset.getDefaultModel();
OntModel ontModel = ModelFactory.createOntologyModel(ontModelSpec, model);
When I now create new resources via API, they are not stored in the TDB. And I'm not able to see the Statments have added via SPARQL?!
The SPAQRL statement shows me only the entries I've added with SPARQL
QueryExecution qExec = QueryExecutionFactory.create(
StrUtils.strjoinNL("SELECT ?s ?p ?prop",
"WHERE {?s ?p ?prop}"),
dataset) ;
ResultSet rs = qExec.execSelect() ;
try {
ResultSetFormatter.out(rs) ;
} finally { qExec.close() ; System.out.println("closed connection");}
and this returns only the Resource added with the API
System.out.print("instance: " + ontModel.getResource(NS + "TestItem"));
And when I call this:
ExtendedIterator<Statement> iter = ontModel.listStatements();
I get the following exception:
org.openjena.atlas.lib.InternalErrorException: Invalid id node for subject (null node): ([0000000000000067], [0000000000000093], [00000000000000C8])
Is someone able to explain that behavior? Or could someone please give me a hint how to separate schema and date with TDB in right way with using the OntModel?
Partial answer:
org.openjena.atlas.lib.InternalErrorException: Invalid id node for subject (null node): ([0000000000000067], [0000000000000093], [00000000000000C8])
You are using TDB without transactions - try adding TDB.sync before exiting to flush changes to the disk.
Basically, I use the Any23 distiller to extract RDF statements from files embedded with RDFa (The actual files where created by DBpedia Spotlight using the xhtml+xml output option). By using Any23 RDFa distiller I can extract the RDF statements (I also tried using Java-RDFa but I could only extract the prefixes!). However, when I try to pass the statements to a Jena model and print the results to the console, nothing happens!
This is the code I am using :
File myFile = new File("T1");
Any23 runner= new Any23();
DocumentSource source = new FileDocumentSource(myFile);
ByteArrayOutputStream outA = new ByteArrayOutputStream();
InputStream decodedInput=new ByteArrayInputStream(outA.toByteArray()); //convert the output stream to input so i can pass it to jena model
TripleHandler writer = new NTriplesWriter(outA);
try {
runner.extract(source, writer);
} finally {
writer.close();
}
String ttl = outA.toString("UTF-8");
System.out.println(ttl);
System.out.println();
System.out.println();
Model model = ModelFactory.createDefaultModel();
model.read(decodedInput, null, "N-TRIPLE");
model.write(System.out, "TURTLE"); // prints nothing!
Can anyone tell me what I have done wrong? Probably multiple things!
Is there any easy way i can extract the subjects of the RDF statements directly from any23 (bypassing Jena)?
As I am quite inexperienced in programming any help would be really appreciated!
You are calling
InputStream decodedInput=new ByteArrayInputStream(outA.toByteArray()) ;
before calling any23 to insert triples. At the point of the call, it's empty.
Move this after the try-catch block.
I am using Entity Framework 4 with the POCO code generator. I have a stored procedure that does an INSERT and returns the ##IDENTITY of the inserted record. I am trying to import the stored procedure as a function in my .edmx file, but I am having trouble using it.
In the model browser, I can see the stored procedure under the database heirarchy, and then I right-click and select "Function Import..." I have tried using "None" as the return type as well as Int32 (even though it says "Collection of.."). The function appears under Function Imports, but even after saving and compiling, I am unable to find the function anywhere in my ObjectContext. I have attempted to delete it and re-import the stored procedure several times with no success.
NOTE: I have another stored procedure that does a straight SELECT and this is imported properly and shows up in the ObjectContext code.
Am I doing something wrong?
If your stored procedure does not return a result set, so you select "Returns a Collection of" "None" in the "Add Function Import" dialog in Visual Studio, then the function import is NOT added as a method on your generated object context. (I have not been able to find out why yet, but I'm still looking.)
The return value from the sproc (e.g., return ##identity) is not what is meant by the "Returns a Collection of" question. Which is why it didn't work. The question is asking about what result set comes back from the sproc.
There are three ways I can think of to handle your problem:
Return your identity value using a select (e.g., select ##identity as Identity) and then specify a collection of Int32 in reply to the "Returns a collection of" question.
Return your identity value using an output clause on your insert statement and get it the same way as in 1.
Use Entity SQL and make the identity value an out parameter. Here is how to do that: How to: Execute a Query Using a Stored Procedure with In and Out Parameters
I hope that helps.
On investigation of the POCO .Context.tt file I found the following code at around line 111
if (edmFunction.ReturnParameter == null)
{
continue;
}
string returnTypeElement = code.Escape(ef.GetElementType(edmFunction.ReturnParameter.TypeUsage));
which means any function imports that return 'none' won't be written.
I have modified my .Context.tt file so that the above code is replaced with
string returnTypeElement = #"";
if (edmFunction.ReturnParameter == null)
{
returnTypeElement = #"void";
} else {
returnTypeElement = code.Escape(ef.GetElementType(edmFunction.ReturnParameter.TypeUsage));
}
I have then had to add some checks around the function declaration (around line 118)
<#
if(returnTypeElement != "void"){
#>
<#=Accessibility.ForMethod(edmFunction)#> ObjectResult<<#=returnTypeElement#>> <#=code.Escape(edmFunction)#>(<#=paramList#>)
<#
} else {
#>
<#=Accessibility.ForMethod(edmFunction)#> <#=returnTypeElement#> <#=code.Escape(edmFunction)#>(<#=paramList#>)
<#
}
#>
and the return statement (around line 142)
<#
if(returnTypeElement != "void"){
#>
return base.ExecuteFunction<<#=returnTypeElement#>>("<#=edmFunction.Name#>"<#=code.StringBefore(", ", String.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray()))#>);
<#
} else {
#>
base.ExecuteFunction("<#=edmFunction.Name#>"<#=code.StringBefore(", ", String.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray()))#>);
<#
}
#>
Now, this might not be the most elegant solution (hard-coding strings!), but it does mean I can use function import on my stored procedures that do not return anything and have the corresponding functions created in the .Context.cs file, and therefore accessible through Intellisense.