我写了这个查询并返回夫妻和特定条件的列表.(在http://live.dbpedia.org/sparql中)
SELECT DISTINCT ?actor ?person2 ?cnt
WHERE
{
{
select DISTINCT ?actor ?person2 (count (?film) as ?cnt)
where {
?film dbo:starring ?actor .
?actor dbo:spouse ?person2.
?film dbo:starring ?person2.
}
order by ?actor
}
FILTER (?cnt >9)
}
Run Code Online (Sandbox Code Playgroud)
问题是某些行是重复的.例:
http://dbpedia.org/resource/George_Burns http://dbpedia.org/resource/Gracie_Allen 12
http://dbpedia.org/resource/Gracie_Allen http://dbpedia.org/resource/George_Burns 12
如何删除这些重复?我将性别添加到?actor但它会损害当前结果.
Natan Cox的答案显示了排除这些伪重复的典型方法.结果实际上并不重复,因为在一个,例如,乔治伯恩斯是?演员,而在另一个,他是?person2.在许多情况下,您可以添加一个过滤器,以要求对这两件事进行排序,这样就可以删除重复的案例.例如,当您有以下数据时:
:a :likes :b .
:a :likes :c .
Run Code Online (Sandbox Code Playgroud)
然后你搜索
select ?x ?y where {
:a :likes ?x, ?y .
}
Run Code Online (Sandbox Code Playgroud)
你可以添加过滤器(?x <?y)来强制执行?x和?y之间的排序,这将排除这些伪重复.但是,在这种情况下,它有点棘手,因为使用相同的标准找不到?actor和?person2.如果DBpedia包含
:PersonB dbo:spouse :PersonA
Run Code Online (Sandbox Code Playgroud)
但不是
:PersonA dbo:spouse :PersonB
Run Code Online (Sandbox Code Playgroud)
然后简单的过滤器将无法工作,因为你永远不会找到主题PersonA小于对象PersonB的三元组.因此,在这种情况下,您还需要稍微修改一下查询以使条件对称:
select distinct ?actor ?spouse (count(?film) as ?count) {
?film dbo:starring ?actor, ?spouse .
?actor dbo:spouse|^dbo:spouse ?spouse .
filter(?actor < ?spouse)
}
group by ?actor ?spouse
having (count(?film) > 9)
order by ?actor
Run Code Online (Sandbox Code Playgroud)
(此查询还表明,你并不需要一个子查询在这里,你可以使用其在聚集值"过滤器").但最重要的部分是使用属性路径DBO:配偶| ^ DBO:配偶找到一个值?配偶,使得无论是 演员DBO:??配偶配偶 或 配偶DBO:??配偶的演员.这使得关系是对称的,因此即使关系仅在一个方向上声明,也可以保证获得所有对.