我如何使用单个 CONSTRUCT 构建关于某些个体的 RDF 图?

How can I build a RDF graph about some individuals with a single CONSTRUCT?

我在 SPARQL 中有一个构造查询,可用于检索有关合同的详细信息:

CONSTRUCT {
?contract dcterm:identifier ?id .
?contract rdfs:label ?label .

?contract pc:bidder ?bidder .
}
WHERE {
    OPTIONAL {
        ?contract dcterm:identifier ?id .
    }
    OPTIONAL {
        ?contract rdfs:label ?label .
    }

    OPTIONAL {
        ?contract pc:tender ?tender .
        ?tender pc:bidder ?bidder .
    }
}

我有一份合同列表,例如 pc:c1、pc:c2,我想在一个查询(或一个 HTTP 调用)中检索它们的详细信息。

第一个想法是用每个uri替换?contract变量,避免其他变量之间的冲突:

CONSTRUCT {
    pc:c1 dcterm:identifier ?id1 .
    pc:c1 rdfs:label ?label1 .

    pc:c1 pc:bidder ?bidder1 .


    pc:c2 dcterm:identifier ?id2 .
    pc:c2 rdfs:label ?label2 .

    pc:c2 pc:bidder ?bidder2 .
}
WHERE {
    OPTIONAL {
        pc:c1 dcterm:identifier ?id1 .
    }
    OPTIONAL {
        pc:c1 rdfs:label ?label1 .
    }

    OPTIONAL {
        ?pc:c1 pc:tender ?tender1 .
        ?tender1 pc:bidder ?bidder1 .
    }
    OPTIONAL {
        pc:c2 dcterm:identifier ?id2 .
    }
    OPTIONAL {
        pc:c2 rdfs:label ?label2 .
    }

    OPTIONAL {
        ?pc:c2 pc:tender ?tender2 .
        ?tender2 pc:bidder ?bidder2 .
    }
}

问题是,对于许多 uris,查询可能会变得相当大。

有没有更简洁的写法?

我尝试使用 IN 运算符 ( https://www.w3.org/TR/2013/REC-sparql11-query-20130321/#OperatorMapping - 17.4.1.9 ),但 Virtuoso 似乎无法解析查询。 此外,VALUES 关键字 ( https://www.w3.org/TR/2013/REC-sparql11-query-20130321/#inline-data ) 似乎是一个很好的解决方案,但 Jena 似乎没有正确解析它。

只需使用 values 指定您想要的 ?contract 的值。 (Jena 确实支持 values,所以您的测试中可能有错字?)它看起来像这样:

CONSTRUCT {
  ?contract dcterm:identifier ?id .
  ?contract rdfs:label ?label .
  ?contract pc:bidder ?bidder .
}
WHERE {
    VALUES ?contract { pc:c1 pc:c2 }         #-- this is the new line
    OPTIONAL {
        ?contract dcterm:identifier ?id .
    }
    OPTIONAL {
        ?contract rdfs:label ?label .
    }

    OPTIONAL {
        ?contract pc:tender ?tender .
        ?tender pc:bidder ?bidder .
    }
}

对于单个 属性 匹配项,您还可以使用属性的 values 使其更短。您还可以使用 属性 路径来缩短投标人部分:

CONSTRUCT {
  ?contract ?p ?o .
  ?contract pc:bidder ?bidder .
}
WHERE {
    VALUES ?contract { pc:c1 pc:c2 } 
    VALUES ?p { dcterm:identifier rdfs:label }
    OPTIONAL {
      ?contract ?p ?o
    }
    OPTIONAL {
        ?contract pc:tender/pc:bidder ?bidder .
    }
}