Hi Scott, thank you for your patience as we work through this. The data fabric capabilities you are looking for are definitely supported by the Stardog platform. I have put an example together that attempts to replicate your use case and will hopefully help us move forward in resolving your issue.
- To start, I created a sample mysql database with a table called "students" with columns STUDENT_ID and STUDENT_NAME. This table has 3 records...Mary, John and Peter.
CREATE TABLE STUDENTS (
STUDENT_ID integer,
STUDENT_NAME char(25)
);
INSERT INTO STUDENTS (STUDENT_ID, STUDENT_NAME) VALUES (1, 'Mary');
INSERT INTO STUDENTS (STUDENT_ID, STUDENT_NAME) VALUES (2, 'John');
INSERT INTO STUDENTS (STUDENT_ID, STUDENT_NAME) VALUES (3, 'Peter');
- I created a Stardog database called "students" and uploaded the following ontology with a Student, Person and Course class. Student is a sub class of Person and Student is related to Course by an "enrolled in" object property.
@prefix test: <urn:test:model:> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
test:Person a owl:Class ;
rdfs:label "Person".
test:Student a owl:Class ;
rdfs:subClassOf test:Person;
rdfs:label "Student".
test:Course a owl:Class;
rdfs:label "Course".
test:enrolled_in a owl:ObjectProperty;
rdfs:label "enrolled in";
rdfs:domain test:Student ;
rdfs:range test:Course.
test:name a owl:DatatypeProperty ;
rdfs:label "name" ;
rdfs:domain test:Student ;
rdfs:range xsd:string .
test:course_name a owl:DatatypeProperty ;
rdfs:label "course name" ;
rdfs:domain test:Course ;
rdfs:range xsd:string .
- In Stardog Studio I created a data source that connects to the mysql database I set up.
- Next I created a new Virtual Graph called "students_vg". Stardog will auto-generates mappings using Stardog's SMS mappings syntax. I chose to modify this mapping to align the source data to my ontology. Please note that the columns STUDENT_ID and STUDENT_NAME from my table become variables that I can pass in to the "TO" clause in the mapping.
PREFIX test: <urn:test:model:>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX stardog: <tag:stardog:api:>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
MAPPING
FROM SQL {
SELECT *
FROM `test`.`students`
}
TO {
?subject a test:Student;
rdfs:label ?STUDENT_NAME;
test:name ?STUDENT_NAME.
} WHERE {
BIND(template("urn:test:data:students:{STUDENT_ID}") AS ?subject)
}
- Now that the Virtual Graph is created I can query it using Stardog Studio's Workspace.
PREFIX test: <urn:test:model:>
select ?student ?studentName {graph <virtual://students_vg> {
?student a test:Student;
rdfs:label ?studentLabel;
test:name ?studentName.
}}
This results in returning 3 records from our virtualized mysql database.
- If we want to add data into Stardog and query across that data and the data from the Virtual Graph, we can do that too. I will show this by inserting 3 instances of the Courses Students are enrolled in:
INSERT DATA {<urn:test:data:students:1> <urn:test:model:enrolled_in> <urn:test:data:course:1>;
<urn:test:model:course_name> "Algebra"}
INSERT DATA {<urn:test:data:students:2> <urn:test:model:enrolled_in> <urn:test:data:course:2>;
<urn:test:model:course_name> "Physics"}
INSERT DATA {<urn:test:data:students:3> <urn:test:model:enrolled_in> <urn:test:data:course:3>;
<urn:test:model:course_name> "Technical Writing"}
Once this data is inserted, we can now query for it and the data in the mysql database to see what courses our students are enrolled in.
PREFIX test: <urn:test:model:>
select ?student ?studentName ?course ?courseName {graph <virtual://students_vg> {
?student a test:Student;
rdfs:label ?studentLabel;
test:name ?studentName.
}
?student test:enrolled_in ?course;
test:course_name ?courseName.
}
I hope this example provided some insights into how Stardog's data fabric capabilities work. To better understand what is going on in your environment, would you be able to share your ontology and virtual graph mappings? Thank you!