代码之家  ›  专栏  ›  技术社区  ›  prgao

提取由一组节点诱导的子图

  •  2
  • prgao  · 技术社区  · 11 年前

    给定对象和有向关系的一般图:

    @prefix obj: <http://example.org/obj/> .
    @prefix rel: <http://example.org/rel/> .
    
    obj:obj1 rel:rel1 obj:obj2 .
    obj:obj3 rel:rel2 obj:obj2 .
    obj:obj9 rel:rel5 obj:obj8 .
    obj:obj1 rel:rel1 obj:obj3 .
    

    以及对象的子集,比如 obj1, obj2, obj3 ,如何使用简单的SPARQL查询从完整图中提取仅包含此对象子集的子图,而不考虑特定关系?生成的子图应该是:

    obj:obj1 rel:rel1 obj:obj2 .
    obj:obj3 rel:rel2 obj:obj2 .
    obj:obj1 rel:rel1 obj:obj3 .
    

    我目前的尝试是尝试使用一堆 OPTIONAL 条款,这可能不是最好的方法:

    SELECT ?r1 ?r2 ?r3 ?r4 ?r5 ?r6 WHERE {
    OPTIONAL {obj:obj1 ?r1 obj:obj2} .
    OPTIONAL {obj:obj1 ?r2 obj:obj3} .
    OPTIONAL {obj:obj2 ?r3 obj:obj3} .
    OPTIONAL {obj:obj2 ?r4 obj:obj1} .
    OPTIONAL {obj:obj3 ?r5 obj:obj1} .
    OPTIONAL {obj:obj3 ?r6 obj:obj2} . }
    
    1 回复  |  直到 11 年前
        1
  •  5
  •   Joshua Taylor    11 年前

    给定这些数据(基本上是您的,除了我添加了 . s在行的末尾,所以它是有效的Turtle,我添加了几个三元组,这样我们就可以看到,仅仅有一个主题或对象不在特殊集合中是否会将三元组排除在结果之外):

    @prefix obj: <http://example.org/obj/> .
    @prefix rel: <http://example.org/rel/> .
    
    obj:obj1 rel:rel1 obj:obj2 .
    obj:obj3 rel:rel2 obj:obj2 .
    obj:obj1 rel:rel4 obj:obj8 . # additional triple
    obj:obj9 rel:rel7 obj:obj2 . # additional triple
    obj:obj9 rel:rel5 obj:obj8 .
    obj:obj1 rel:rel1 obj:obj3 .
    

    您可以使用这样的查询:

    prefix obj: <http://example.org/obj/>
    
    select ?s ?p ?o where { 
      values ?s { obj:obj1 obj:obj2 obj:obj3 }
      values ?o { obj:obj1 obj:obj2 obj:obj3 }
      ?s ?p ?o .
    }
    

    要获得这样的结果:

    $ sparql --query query.rq --data data.n3
    ----------------------------------
    | s        | p        | o        |
    ==================================
    | obj:obj1 | rel:rel1 | obj:obj3 |
    | obj:obj1 | rel:rel1 | obj:obj2 |
    | obj:obj3 | rel:rel2 | obj:obj2 |
    ----------------------------------
    

    使用 values 这里只是这么说 ?s 必须从一组特定的值中提取,并且 ?o 必须从一组特定的值中提取。我认为没有办法避免在每个地点重复特殊资源的列表。也就是说,你必须写 { obj:obj1 obj:obj2 obj:obj3 } 两次,但这仍然比列举所有可能的组合容易得多。

    您也可以考虑使用 construct 在这里,而不是 select ,如果您想要返回的实际上是图形,而不是一组变量绑定。例如,使用此查询:

    prefix obj: <http://example.org/obj/>
    
    construct { ?s ?p ?o } where { 
      values ?s { obj:obj1 obj:obj2 obj:obj3 }
      values ?o { obj:obj1 obj:obj2 obj:obj3 }
      ?s ?p ?o .
    }
    

    您可以返回实际的RDF图:

    $ sparql -out TTL --query query.rq --data data.n3
    @prefix obj:   <http://example.org/obj/> .
    @prefix rel:   <http://example.org/rel/> .
    
    obj:obj1  rel:rel1  obj:obj3 , obj:obj2 .
    
    obj:obj3  rel:rel2  obj:obj2 .
    
    $ sparql -out N-Triples --query query.rq --data data.n3
    <http://example.org/obj/obj1> <http://example.org/rel/rel1> <http://example.org/obj/obj3> .
    <http://example.org/obj/obj1> <http://example.org/rel/rel1> <http://example.org/obj/obj2> .
    <http://example.org/obj/obj3> <http://example.org/rel/rel2> <http://example.org/obj/obj2> .
    
    $ sparql -out RDF/XML --query query.rq --data data.n3
    <rdf:RDF
        xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
        xmlns:obj="http://example.org/obj/"
        xmlns:rel="http://example.org/rel/">
      <rdf:Description rdf:about="http://example.org/obj/obj1">
        <rel:rel1>
          <rdf:Description rdf:about="http://example.org/obj/obj3">
            <rel:rel2 rdf:resource="http://example.org/obj/obj2"/>
          </rdf:Description>
        </rel:rel1>
        <rel:rel1 rdf:resource="http://example.org/obj/obj2"/>
      </rdf:Description>
    </rdf:RDF>