带有TDB的Jena规则引擎

时间:2013-07-11 22:45:27

标签: java jena rule-engine tdb jena-rules

我在TDB模型中加载了数据并使用Jena编写了一些规则以便应用到TDB中。然后我将推断的数据存储到新的TDB中。

我将上面的案例应用于一个小的数据集~200kb并且措辞得很好。但是,我的实际TDB是2.7G,计算机已经运行了大约一个星期,它实际上仍在运行。

这是正常的,还是我做错了什么?使用Jena规则引擎的替代方法是什么?

以下是一小段代码:

public class Ruleset {
  private List<Rule> rules = null; 
  private GenericRuleReasoner reasoner = null;

  public Ruleset (String rulesSource){
    this.rules = Rule.rulesFromURL(rulesSource);
    this.reasoner = new GenericRuleReasoner(rules);
    reasoner.setOWLTranslation(true);           
    reasoner.setTransitiveClosureCaching(true);
  }

  public InfModel applyto(Model mode){
    return ModelFactory.createInfModel(reasoner, mode);
  }

  public static void main(String[] args) {
    System.out.println(" ... Running the Rule Engine ...");
    String rulepath = "src/schemaRules.osr";
    Ruleset rule = new Ruleset (rulepath);
    InfModel infedModel = rule.applyto(data.tdb);
    infdata.close();
  }
}

2 个答案:

答案 0 :(得分:2)

持久性商店中的大型数据集与Jena的规则系统不匹配。基本问题是RETE engine会在规则传播期间对图表进行许多小查询。正如您所发现的那样,对任何持久性存储(包括TDB)进行这些查询的开销往往会使执行时间长得无法接受。

根据您使用推理的目标,您可能有其他选择:

  • 将数据加载到足够大的内存图中,然后在单个事务中将推理闭包(基本图形和蕴涵)保存到TDB存储中。此后,您可以查询商店,而不会产生规则系统的开销。显然,更新可能是这种方法的一个问题。

  • 像现在一样在TDB中存储您的数据,但是将子集动态加载到内存模型中以使用实时推理。使更新更容易(只要更新内存副本和持久存储),但需要对数据进行分区。

如果您只想要一些基本推论,例如关闭rdfs:subClassOf层次结构,则可以使用infer命令行工具生成可以加载到TDB的推理闭包:

$ infer -h
infer --rdfs=vocab FILE ...
General
  -v   --verbose         Verbose
  -q   --quiet           Run with minimal output
  --debug                Output information for debugging
  --help
  --version              Version information

推断可以更高效,因为它不需要大内存模型。但是,它会在计算中得到限制。

如果这些都不适合您,您可能需要考虑商业推理引擎,例如OWLIMStardog

答案 1 :(得分:0)

谢谢伊恩。

我实际上能够通过SPARQL更新来做到这一点,因为DAVE建议我完成这项工作仅用了10分钟。

以下是代码示例:

System.out.println(" ... Load rules ...");
    data.startQuery();
    String query = data.loadQuery("src/sparqlUpdatesRules.tql");
    data.endQuery();

    System.out.println(" ... Inserting rules ...");
    UpdateAction.parseExecute(query, inferredData.tdb);

    System.out.println(" ... Printing RDF ...");
    inferredData.exportRDF();

    System.out.println(" ... closeing  ...");
    inferredData.close();

以下是SPARQL更新的示例:

INSERT {
   ?w ddids:carries ?p .
} WHERE {
   ?p ddids:is_in ?w .
}; 

感谢您的回答