【问题标题】:Add basic value to Ontology individuals @Jena为本体个人增加基本价值@Jena
【发布时间】:2014-10-07 11:00:45
【问题描述】:

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

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 添加到“事物”,因为它是 OWL 本体中最基本的类型。

【问题讨论】:

  • 顺便说一句,您是否尝试过映射您的数据,然后将三元组存储在三元组存储中?那么你就不需要你的原始数据库了。为此,您可以使用 Jena TDB。
  • 我已经使用了一些数据库,并且已经需要一个 3.4 GB 的 Java 堆空间。我不认为我会将本体三元组存储为文件。但感谢您的建议
  • 请注意,TDB 使用内存映射文件 IO 并智能分页其索引。对于原本可以存储在内存中的小型数据集,TDB 速度较慢,但​​是当数据集变得太大而无法存储在内存中时,它会继续运行。我只用 4 GB 内存就运行了多达 2700 万个三元组。然而,TDB 的索引需要lot 的磁盘空间。

标签: java mysql jena ontology preloading


【解决方案1】:

乍一看还不错。一个技巧是尝试将 Jena 模型转换为 RDF 序列化并通过 Protégé 运行它,以更清楚地了解您的本体映射的外观。

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

@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。这是一个定义非常好的词汇表,即使它不用于商业用途,也可以描述信息。特别是查看那里的课程。

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

【讨论】:

    【解决方案2】:

    以编程方式生成 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,您可以在该属性上为您的 :DatabaseResources 定义一个 OWL-2 Key,并保持与数据库中相同的语义。

    编辑:在耶拿邮件列表中注明您的部分帖子:

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

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

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

    【讨论】:

    • 嗯,我喜欢你的想法。现在我正在考虑一个超类DatabaseEntity,所有子类都应该至少有一个DatabaseIdentifier。这样我就可以保持“事物”的清洁,以后可以有没有 ID 的课程。
    • 您还可以拥有类层次结构的正交部分。例如,:person1 可能已从数据库中提取,而 :person2 稍后会添加到您的持久数据中。您可以将foaf:Person:DatabaseEntity 添加为:person1 的类型,但只为:person2 添加foaf:Person。这样,您就不必假设您的整个层次结构会随着您的知识库的发展而扩展 :DatabaseEntity
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多