Java 为本体个体@Jena添加基本价值
我有一个本体,其中包含一些类和要运行的所有设置。用个人和数据填充它的好方法是什么??简而言之,做一个从数据库(作为输入)到本体的单向映射Java 为本体个体@Jena添加基本价值,java,mysql,jena,ontology,preloading,Java,Mysql,Jena,Ontology,Preloading,我有一个本体,其中包含一些类和要运行的所有设置。用个人和数据填充它的好方法是什么??简而言之,做一个从数据库(作为输入)到本体的单向映射 public class Main { static String SOURCE = "http://www.umingo.de/ontology/bento.owl"; static String NS = SOURCE+"#"; public static void main(String[] args) throws Exception {
public class Main {
static String SOURCE = "http://www.umingo.de/ontology/bento.owl";
static String NS = SOURCE+"#";
public static void main(String[] args) throws Exception {
OntModel model = ModelFactory.createOntologyModel( OntModelSpec.OWL_MEM );
// read the RDF/XML file
model.read(SOURCE);
OntologyPreLoader loader = new OntologyPreLoader();
model = loader.init(model);
model.write(System.out,"RDF/XML");
}
}
我的预加载程序有一个方法init,目标是将数据从数据库复制到本体中。这是摘录
public OntModel init(OntModel model) throws SQLException{
Resource r = model.getResource( Main.NS + "Tag" );
Property tag_name = model.createProperty(Main.NS + "Tag_Name");
OntClass tag = r.as( OntClass.class );
// statements allow to issue SQL queries to the database
statement = connect.createStatement();
// resultSet gets the result of the SQL query
resultSet = statement
.executeQuery("select * from niuu.tags");
// resultSet is initialised before the first data set
while (resultSet.next()) {
// it is possible to get the columns via name
// also possible to get the columns via the column number
// which starts at 1
// e.g., resultSet.getSTring(2);
String id = resultSet.getString("id");
String name = resultSet.getString("name");
Individual tag_tmp = tag.createIndividual(Main.NS+"Tag_"+id);
tag_tmp.addProperty(tag_name,name);
System.out.println("id: " + id);
System.out.println("name: " + name);
}
return model;
}
一切都正常,但我真的不确定这种预加载本体的方法。此外,每个人都应该有自己的ID,以便我可以在以后将其与数据库进行匹配。
我可以简单地定义一个属性ID并将其添加到每个人吗
我考虑将ID添加到“Thing”中,因为它是OWL本体中最基本的类型 乍一看似乎还可以。一个技巧是尝试将Jena模型转换为RDF序列化,并通过Protégé运行它,以便更清楚地了解本体映射的外观 你完全可以制作自己的属性来描述每个人的id。 下面是一个关于如何以turtle格式创建类似属性的示例。(我没有为OWL和rdfs添加前缀,因为它们很常见) 如果需要,您也可以在Jena中添加此项。(或者将其加载到Jena中的模型中。)
@前缀您:。
您可以使用:dbIdentificator或owl:DatatypeProperty。
您:dbIdentificator rdfs:label”“@en。
您:dbIdentificator rdfs:comment”“@en。
您:dbIdentificator rdfs:isDefinedBy。
你:dbIdentificator rdfs:域owl:东西。
您还可以将owl:Thing添加到每个资源中,但这不是最佳实践,因为它是对资源的模糊定义。我会四处寻找更多定义资源的词汇表。看一看。这是一个非常好的定义词汇表,可以描述信息,即使它不是用于商业用途。特别是看看那里的课程
希望这回答了您的一些问题。以编程方式生成URI总是有点令人不安。如果您有Guava,那么可以使用它对数据库中的内容进行一些快速失败的断言(这样,您的代码就会让您知道它是否与您的模式不一致)。使用JDK确保从数据库获得的
id
被转换为URI友好的格式(请注意,如果您的数据包含无法以xml打印且没有百分比编码的字符,则需要手动处理它们)
对于属性/列值,请使用显式创建文本。这非常清楚您是使用普通文本、语言文本还是类型化文本:
//例如,如果事物可以有多种语言的多个名称
tag_tmp.addProperty(tag_name,model.createTypedLiteral(name,“en”));
请注意,您可能不希望定义模式以使其包含有关owl:Thing
的内容,因为这将在您的域之外产生影响。相反,定义一个特定于域的概念,如:DatabaseResource
。将属性的域设置为那样,它是子类而不是对象。通过这种方式,属性的使用意味着主题在您的域中,而不仅仅是一个owl个体(这是由owl:DatatypeProperty
域暗示的)
编辑:创建数据库唯一ID的表示并将其放入RDF模型是完全可以接受的。如果您使用的是owl2,那么您可以为:DatabaseResource
s在该属性上定义,并保持与数据库中相同的语义
编辑:在Jena邮件列表中注明您的部分帖子:
我有一个用于只读目的的大型MYSQL数据库,希望将一些数据提取到本体中
我强烈建议使用构建一个由磁盘支持的数据集。我以前曾处理过非常大的数据库导出,否则很可能无法处理数据大小。TDB的索引需要大量磁盘空间,但内存映射IO由于OOM错误而很难消除。最后,一旦在磁盘上构建了数据库,就不必再次执行这种昂贵的导入操作(或者至少可以对其进行优化)
如果您发现数据库创建时间过长,那么您可能需要以创造性的方式使用批量加载程序。有一个使用java批量加载程序的示例。Btw,您是否尝试映射数据,然后将三元组存储在三元组存储中?那么您就不需要原始数据库了。你可以使用Jena TDB来实现这个目的。我已经使用了一些数据库,并且已经需要一个3,4 GB的java heapspace。我不认为我会将本体Triples存储为文件。但感谢您的建议注意,TDB使用内存映射文件IO并智能地分页其索引。对于本来可以存储在内存中的小数据集,TDB速度较慢,但当数据集变得太大而无法存储在内存中时,它会继续运行。我已经用4 GB内存运行了多达2700万个三元组的TDB。TDB的索引需要大量的磁盘空间。嗯,我喜欢你的想法。现在我考虑一个超类DatabaseEntity,所有子类都应该至少有一个DatabaseIdentifier。这样我可以保持“东西”干净,以后可以有没有ID的类。你也可以有你的类层次结构的正交部分。例如,:person1
可能已从数据库中提取,而:person2
稍后已添加到持久数据中。您可以将foaf:Person
和:DatabaseEntity
添加为:person1
的类型,但只能为:person2
添加foaf:Person
。这样,您就不必假设整个层次结构随着知识库的发展而扩展。
@prefix you: <your domain> .
you:dbIdentificator a owl:DatatypeProperty .
you:dbIdentificator rdfs:label "<Your database identifcator>"@en .
you:dbIdentificator rdfs:comment "<Some valuable information if needed>"@en .
you:dbIdentificator rdfs:isDefinedBy <your domain> .
you:dbIdentificator rdfs:domain owl:Thing .