我有以下DBpedia SPARQL,它展示了影响哲学家的哲学家。但是,当哲学家有多个foaf:name时,它会返回重复项:
SELECT ?name ?influencedName
WHERE {
?philosopher a dbpedia-owl:Philosopher ;
dbpedia-owl:influenced ?influenced ;
foaf:name ?name .
?influenced a dbpedia-owl:Philosopher ;
foaf:name ?influencedName .
}SPARQL results
如果?name和?includedName有多个值,如何返回单个名称。我会喜欢第一个,或者选择最少的字符来保留。
这是柏拉图影响伯特兰·罗素的另一个例子。我想让它返回一行,但我得到了四行:
SELECT ?name ?influencedName
WHERE {
?philosopher a dbpedia-owl:Philosopher ;
dbpedia-owl:influenced ?influenced ;
foaf:name ?name , "Plato"@en .
?influenced a dbpedia-owl:Philosopher ;
foaf:name ?influencedName, "Bertrand Arthur William Russell, 3rd Earl Russell"@en .
}SPARQL results
发布于 2013-06-16 09:23:34
查询
听起来你想要一个类似这样的查询:
SELECT ?philosopher ?pName ?influence (SAMPLE(?iName) as ?iName)
WHERE {
# This subquery selects all the philosophers and
# selects just one of their names .
{
SELECT ?philosopher (SAMPLE(?pName) as ?pName) WHERE {
?philosopher a dbpedia-owl:Philosopher ;
foaf:name ?pName .
}
GROUP BY ?philosopher
}
# This main query selects the influence of the
# philosophers and select their names. The GROUP
# BY on the outer query puts all the
# (?philosopher,?pName,?influence,?iName) tuples
# that have the same ?philosopher, ?pName, and
# influence together, and the (SAMPLE(?iName) as ?iName)
# in the outer SELECT combines them all, choosing an
# arbitrary representative ?iName.
?influence dbpedia-owl:influenced ?philosopher ;
a dbpedia-owl:Philosopher ;
foaf:name ?iName .
}
GROUP BY ?philosopher ?pName ?influenceSPARQL results
如果您只对名称感兴趣,而不关心实际资源的选择,那么您不需要在最外层的SELECT中使用?philosopher和?influence,可以使用它们
SELECT ?pName (SAMPLE(?iName) as ?iName)
WHERE { …SPARQL results
您可能还想在末尾添加一个ORDER BY,以使结果更易于检查:
…
GROUP BY ?philosopher ?pName ?influence
ORDER BY ?pNameSPARQL results
对于柏拉图来说,这些最后的结果包括以下几行:
"Plato"@en "Socrates"@en
"Plato"@en "Parmenides"@en
"Plato"@en "Zeno of Elea"@en
"Plato"@en "Pythagoras"@en
"Plato"@en "Gorgias"@en
"Plato"@en "Protagoras"@en
"Plato"@en "Heraclitus"@en在我在这里编写的查询中,我使用SAMPLE任意选取一个哲学家的foaf:name,但是在aggregate algebra中还有其他函数可以用来选择值。如果你想让‘first’值按顺序排列,你可能会对Min感兴趣。
子查询、GROUP BY、SAMPLE、MIN等
这实际上与SPARQL规范的Section 12, Subqueries中的子查询示例非常相似。在该示例中,下面的查询用于选择Alice认识的人,并且对于每个人,只选择其中一个人的姓名:
PREFIX : <http://people.example/>
SELECT ?y ?minName
WHERE {
:alice :knows ?y .
{
SELECT ?y (MIN(?name) AS ?minName)
WHERE {
?y :name ?name .
} GROUP BY ?y
}
}这并不难适应哲学影响的问题。哲学家问题首先选择所有哲学家及其名称,按实际的哲学家资源进行分组,并使用sample为每个哲学家选择一个代表性名称。外部查询也做同样的事情,但它不是选择哲学家,而是选择影响每个哲学家的实体。对结果进行分组,并选择影响的代表性名称。
发布于 2013-06-17 00:52:31
我已经确定了如何为一个哲学家选择唯一的名称,参见下面的sparql,它为每个哲学家返回一个名称。
但是,我不明白为什么要将此合并到更大的查询中,该查询返回哲学家和受影响的哲学家的名称,而不为每个哲学家运行一次此代码,这将是一个庞大而笨拙的查询。我的感觉是,如果我分别运行哲学家姓名和受查询影响的哲学家姓名,并在代码中查找姓名,而不是sparql,我的代码将更具可读性。也许我遗漏了一些sparql特性,这些特性可以让这一切变得简单。敬请指教
以下是我如何获得唯一名称的描述:
从foaf:names和dbprop:names筛选器中获取哲学家的所有名称以仅包含至少包含一个拉丁字母字符( A-Z )的名称查找最短名称的长度从所有最短名称中选择最短的名称
PREFIX dbpedia: <http://dbpedia.org/>
PREFIX dbpedia-owl: <http://dbpedia.org/ontology/>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX dbpprop: <http://dbpedia.org/property/>
SELECT ?philosopher (min(?name) as ?minName)
WHERE {{
?philosopher foaf:name ?name .
} UNION {
?philosopher dbpprop:name ?name .
}
FILTER( strlen(?name) = ?minLength ) . # get the shortest names
FILTER( REGEX( str(?name) , "[A-Z]" )) . # exlude names with no latin charachters
{
SELECT ?philosopher (min(strlen(?name)) as ?minLength)
WHERE {{
?philosopher a dbpedia-owl:Philosopher ;
foaf:name ?name .
} UNION {
?philosopher a dbpedia-owl:Philosopher ;
dbpprop:name ?name .
}
FILTER( REGEX( str(?name) , "[A-Z]" )) .
}
GROUP BY ?philosopher
}
}
GROUP BY ?philosopher
ORDER BY ?philosopherhttps://stackoverflow.com/questions/17129225
复制相似问题