为Ontology个人@Jena添加基本价值

时间:2014-10-07 11:00:46

标签: java mysql jena ontology preloading

我有一个带有一些类的Ontology和所有要运行的设置。填写个人和数据的好方法是什么?简而言之,从数据库(作为输入)到本体的单向映射。

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");

 }
}

My Preloader有一个方法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本体中最基本的类型。

2 个答案:

答案 0 :(得分:1)

乍一看似乎没问题。一个提示是尝试将Jena模型转换为RDF序列化并通过Protégé运行它以更清晰地了解您的本体映射的外观。

你绝对可以创建自己的财产来描述每个人的身份。 下面是一个关于如何以乌龟格式创建类似属性的示例。(我没有添加OWL和rdfs的前缀,因为它们是常见的) 如果需要,你可以在耶拿添加它。 (或将其加载到耶拿的模型中。)

@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  .

您还可以将owl:Thing添加到每个资源中,但这不是最佳实践,因为它是对资源的模糊定义。我会四处寻找能够定义更多资源的词汇表。看看GoodRelations。它是一个非常好的定义词汇表,可以描述信息,即使它不是用于商业用途。特别是看看那里的课程。

希望能回答你的一些问题。

答案 1 :(得分:1)

以编程方式生成URI总是有点令人不安。如果您有Guava,请使用Preconditions对数据库中的内容进行一些快速失败的断言(这样,如果代码与您的模式不一致,您的代码就会通知您)。使用JDK的URLEncoder确保从数据库获得的id转换为URI友好格式(请注意,如果您的数据包含无法以xml格式打印且没有百分比编码的字符,你需要手动处理它们。)

对于属性/列值,请使用显式创建文字。这清楚地表明您是使用普通文字,语言文字还是键入的文字:

// If things can have multiple names in multiple languages, for example
tag_tmp.addProperty(tag_name,model.createTypedLiteral(name, "en"));

请注意,您可能不希望定义架构,因此它暗示了owl:Thing的内容,因为这会影响您的域外。相反,定义特定于域的概念,如:DatabaseResource。将属性的域设置为它,它是子类而不是东西。这样,您的财产的使用意味着您所在域内的主体,而不仅仅是一个猫头鹰个体(无论如何都由owl:DatatypeProperty域隐含)。

编辑:创建数据库唯一ID的表示并将其放入RDF模型是绝对可以接受的。如果您使用的是owl2,则可以在该属性上为:DatabaseResource定义OWL-2 Key,并保留与数据库中相同的语义。

编辑:在Jena邮件列表中注明您的部分内容:

  

我有一个巨大的MYSQL数据库,仅供读取使用,并希望将一些数据提取到本体中。

我强烈建议您使用TDB Java API构建由磁盘支持的Dataset。我之前曾经在进行过非常大的数据库导出,但很可能你的数据大小不会被处理掉。 TDB的索引需要大量磁盘空间,但内存映射IO使得由于OOM错误导致很难杀死。最后,一旦在磁盘上构建了数据库,就不必再次执行这种昂贵的导入操作(或者至少可以对其进行优化)。

如果您发现数据库创建时间过长,那么您可能会以创造性的方式使用批量加载程序。 This answer有一个使用java的批量加载器的例子。