带关系运算符的SPARQL查询

7 投票
1 回答
6696 浏览
提问于 2025-04-18 18:02

我想在SPARQL查询中使用关系与/或运算符

这里是查询:

SELECT DISTINCT ?dbpedia_link str(?name) as ?label str(?label1) as ?label1 ?freebase_link WHERE {
            ?dbpedia_link rdfs:label ?label1 . 
            ?dbpedia_link foaf:name ?name .
            {
                { ?dbpedia_link rdf:type dbpedia-owl:Film .}
                UNION
                { ?dbpedia_link rdf:type dbpedia-owl:Person .}
            }
            ?dbpedia_link owl:sameAs ?freebase_link .
            FILTER regex(?freebase_link, "^http://rdf.freebase.com") .
            FILTER (lang(?label1) = 'en'). 
            ?name bif:contains "Akshay_Kumar" . 
            ?dbpedia_link dcterms:subject ?sub 
        }

在这个查询中,我使用了Akshay_Kumar这个单一名字。现在我想知道,如何同时使用多个名字,利用关系与/或运算符。简单来说,就是我们如何在SPARQL中使用关系运算符

执行SPARQL查询的链接是:http://dbpedia.org/sparql

1 个回答

10

连接

AND 很简单。如果你想说 X 和 Y 通过属性 P 有关系,同时也和 Z 通过属性 Q 有关系,你只需要写出这两个关系:

X P Y .
X Q Z .

这可以简化为:

X P Y ;
Q Z .

现在,如果这两个属性是一样的,也就是说你想说 X 和 Y、Z 都通过属性 P 有关系,那就变成:

X P Y ;
  P Z .

SPARQL 提供了一种简写方式(这个和 RDF 的 Turtle 表示法是一样的):

X P Y, Z .

选择

OR 就稍微复杂一点,但你已经展示了一种方法。如果你想说 X 和 Y 或者 Z 有关系,你可以这样写:

{ X P Y } UNION { X P Z }

SPARQL 1.1 包含了 VALUES,这可以让这个过程简单一些:

VALUES ?xpValue { Y Z }
X P ?xpValue

更新你的查询

你的查询实际上并不符合 SPARQL 1.1(或 SPARQL)的标准,尽管 Virtuoso(DBpedia 运行的端点)接受它。你可以用 sparql.org 的查询验证工具 来测试一下。另外,你注意到你使用了 bif:contains,这个是用来检查字符串是否包含的,但 SPARQL 1.1 实际上提供了一个 contains 函数可以使用。它还提供了 strstarts,可以更高效地识别 freebase 链接。还有 langMatches,这是检查字符串语言标签的正确方法。使用这些,我会把你的查询改写成如下形式,这样可以找到名字中包含“John”或“Mary”的资源。(限制只是为了让这个例子结果更简短。)

select ?resource ?name ?label ?freebase where {
  values ?type { dbpedia-owl:Film dbpedia-owl:Person }
  values ?namePart { "John" "Mary" }

  ?resource rdfs:label ?label ;
            foaf:name ?name ;
            a ?type ;
            owl:sameAs ?freebase .

  filter ( langMatches( lang(?label), 'en' ) &&
           strstarts(str(?freebase), "http://rdf.freebase.com" ) &&
           contains( ?name, ?namePart ) )
}
limit 10

SPARQL 结果

撰写回答