【问题标题】:Recursive query in GRAQL?GRAQL 中的递归查询?
【发布时间】:2020-09-07 13:06:49
【问题描述】:

有没有办法在 GRAQL 中定义递归查询,即匹配实体之间的确切谓词路径未知的模式(例如,有多少个)?

SPARQL 在 1.1 版本中增加了对这些的支持。来自Apache Jena Documentation 的示例:

# Find the types of :x, following subClassOf
SELECT *
{
   :x  rdf:type/rdfs:subClassOf*  ?t
}

CYPHER 从一开始也允许它们。示例:

MATCH (alice:Person { name:"Alice" })-[:friend *1..2]->(friend:Person)
RETURN friend.name;

是否可以在 GRAQL 中做类似的事情?

【问题讨论】:

    标签: graph-databases vaticle-typedb vaticle-typeql knowledge-graph


    【解决方案1】:

    使用 Grakn 的推理引擎可以在 Graql 中实现这一点。

    Graql match 查询不支持循环查询语法(目前尚在计划中),但您可以使用 rule 在 Grakn 中定义递归逻辑。为了实现递归,应该有一个规则在其when 中包含与在规则的then 中推断的类型相同的内容。

    在 Graql 中,这个确切的 friend 示例如下所示。此示例不使用递归,因为我们只寻找 1 或 2 跳循环。

    首先你需要一个模式:

    define
    
    name sub attribute, value string;
    
    person sub entity,
      has name,
      plays friend;
    
    friend sub relation,
      relates friend;
    

    如果这是您的起始架构,您需要按如下方式扩展它,以便在新的 n-degree-friendship 关系中添加递归:

    define
    
    friend-of-a-friend isa relation,
      relates connected-friend;
    
    person sub entity,
      plays connected-friend;
    
    infer-friend-of-a-friend sub rule,
    when {
      (friend: $p1, friend: $p2) isa friendship;
      (friend: $p2, friend: $p3) isa friendship;
    }, then {
      (connected-friend: $p1, connected-friend: $p3) isa friend-of-a-friend;
    };
    

    然后你可以查询任意数量的friendship关系连接的朋友为:

    match $p1 isa person, has name "John"; 
    $p2 isa person, has name $n;
    { (connected-friend: $p1, connected-friend: $p2) isa friend-of-a-friend; } 
    or { (friend: $p1, friend: $p2) isa friendship; };
    get $n;
    

    这个friend 示例不是递归的,但可以扩展为递归。 Grakn 目前不支持的是循环次数。

    我们可以在 subClassOf 示例中看到一个很好的递归示例:

    define
    
    class sub entity,
      plays subclass,
      plays superclass;
    
    class-hierarchy sub relation,
      relates subclass,
      relates superclass;
    
    class-hierarchy-is-recursive sub rule,
    when {
      (subclass: $c1, superclass: $c2) isa class-hierarchy;
      (subclass: $c2, superclass: $c3) isa class-hierarchy;
    }, then {
      (subclass: $c1, superclass: $c3) isa class-hierarchy;
    };
    

    然后匹配找到x的所有子类:

    match $x isa class; 
    $y isa class; 
    (superclass: $x, subclass: $x) isa subclass;
    get $y;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-12
      • 2020-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多