在SPARQL中选择一些不同的标签和一些非不同的标签

16

我正在尝试查询DBPedia中关于本体类别的属性列表,但由于人类可读的“标签”并不总是清晰明了,我还想提供一个来自数据库的示例。问题在于虽然我想选择所有不同的属性,但我只想要每个属性的单个示例。

这里是没有捕获示例的查询方式:

SELECT DISTINCT ?prop ?title WHERE {
    ?thing ?prop [].
    ?thing a <http://dbpedia.org/ontology/Currency>.
    ?prop rdf:type rdf:Property.
    ?prop rdfs:label ?title.
} ORDER BY DESC(COUNT(DISTINCT ?thing))
LIMIT 100
如果我按照这种方式进行更改,我会开始获取重复的?prop值:
SELECT DISTINCT ?prop ?title ?example WHERE {
    ?thing ?prop ?example.
    ?thing a <http://dbpedia.org/ontology/Currency>.
    ?prop rdf:type rdf:Property.
    ?prop rdfs:label ?title.
} ORDER BY DESC(COUNT(DISTINCT ?thing))
LIMIT 100

我非常新手使用SPARQL和数据库查询,因此我不太清楚如何做到这一点。理想情况下,我希望有类似于DISTINCT(?prop) ?title ?example这样的东西,它选择每个prop的唯一值,并返回其标题和示例。

3个回答

10
在您的第二个查询中,“distinct”适用于?prop?title?example的值组合。因此,您不会得到任何重复项,例如在第二个查询中获取的以下两行数据:
dbpedia2:subunitName    "subunit name "@en  "cent"@en
dbpedia2:subunitName    "subunit name "@en  "centavo"@en

它们不是重复的,因为第三行 ?example 有两个不同的值 "cent"@en"centavo"@en

解决这个问题的一种可能的方法是使用 GROUP BYMIN,仅获取 ?label?example 的最低排名值,即:

SELECT ?prop MIN(?title) MIN(?example) WHERE {
    ?thing ?prop ?example.
    ?thing a <http://dbpedia.org/ontology/Currency>.
    ?prop rdf:type rdf:Property.
    ?prop rdfs:label ?title.
} GROUP BY ?prop

这个代码运行得很好,但是GROUP BY参数必须吗?我已经使用ORDER BY DESC(COUNT(DISTINCT ?thing))实现了它,似乎仍然可以工作。是否存在一种情况,ORDER BY会给出一些不愉快的结果,而GROUP BY不会? - Paul
2
@Paul 要成为一个合法的查询,你不能直接按聚合排序 - 这是 SPARQL 1.1 规范不允许的。这可能是 Virtuoso 的扩展,会使查询不可移植,即它不一定适用于非 Virtuoso 端点。请参见我的答案,了解应该做同样事情并且可移植的替代查询形式。 - RobV

5

以下是使用子查询实现您想要的另一种方法:

SELECT ?prop ?title ?example 
WHERE 
{
    ?thing a <http://dbpedia.org/ontology/Currency>.
    ?prop rdf:type rdf:Property.
    { SELECT ?title ?example WHERE { ?thing ?prop ?example . ?prop rdfs:label ?title. } LIMIT 1 }
}
LIMIT 100

这样做的好处是符合SPARQL 1.1标准,正如我在评论中所说的,按聚合排序不被标准允许,因此您正在使用供应商特定的扩展,这将限制查询的可移植性。
如果您确实想以一种在SPARQL 1.1实现中可移植的方式按聚合值排序,则必须首先进行投影,如下所示:
SELECT ?s (COUNT(?p) AS ?predicates) WHERE
{
  ?s ?p ?o
} GROUP BY ?s ORDER BY DESC(?predicates)

2

如果您不关心示例但关心速度,SAMPLEGROUP BY快得多。

SELECT ?prop (SAMPLE(?title) AS ?title) (SAMPLE(?example) AS ?example) 
WHERE {
    ?thing ?prop ?example.
    ?thing a <http://dbpedia.org/ontology/Currency>.
    ?prop rdf:type rdf:Property.
    ?prop rdfs:label ?title.
} LIMIT 100

在dbpedia上,您可能不会注意到差异,因为它会缓存查询结果,但是在使用其他端点时,我注意到了巨大的差异。

我遇到了与op相同的问题,当创建一个查询多个sparql端点的自动完成服务时。我需要找到与搜索术语相关的单个链接,其中链接本身并不是非常重要,但查询速度非常重要。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接