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

Pau*_*aul 12 rdf distinct sparql dbpedia

我正在尝试查询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
Run Code Online (Sandbox Code Playgroud)

如果我以这种方式更改它,我开始为?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
Run Code Online (Sandbox Code Playgroud)

我一般都非常习惯使用SPARQL和数据库查询,因此我不清楚如何执行此操作.理想情况下,我有类似DISTINCT(?prop)?title?example的内容,它为prop选择每个唯一值,并返回其标题和示例.

Man*_*res 8

在你的第二个查询的不同适用于值的组合?prop ?title?example.因此,您没有获得任何重复项,例如在第二个查询中获得的以下两行:

dbpedia2:subunitName    "subunit name "@en  "cent"@en
dbpedia2:subunitName    "subunit name "@en  "centavo"@en
Run Code Online (Sandbox Code Playgroud)

他们不重复,因为第三排?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
Run Code Online (Sandbox Code Playgroud)

  • @Paul要成为正确的有效查询,您不能直接对聚合进行ORDER BY - SPARQL 1.1规范不允许这样做.这可能是一个Virtuoso扩展,并将使查询不可移植,即它不一定适用于非Virtuoso端点.请查看我的答案,以获取可以执行相同操作并可移植的替代查询表单 (2认同)

Rob*_*obV 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
Run Code Online (Sandbox Code Playgroud)

这具有符合 SPARQL 1.1 标准的优点,正如我在评论中所述,标准不允许按聚合排序,因此您使用的是供应商特定的扩展,这将限制查询的可移植性。

如果您确实希望以跨 SPARQL 1.1 实现可移植的方式按聚合值排序,那么您必须首先像这样进行投影:

SELECT ?s (COUNT(?p) AS ?predicates) WHERE
{
  ?s ?p ?o
} GROUP BY ?s ORDER BY DESC(?predicates)
Run Code Online (Sandbox Code Playgroud)