我们先看一个案例。对于 Geffrye,会出现重复结果,因为数据中存在多个经度,如以下查询所示:
SELECT ?museum ?latitude ?longitude
WHERE {
VALUES ?museum { dbpedia:Geffrye_Museum }
?museum a dbpedia-owl:Museum ;
geo:lat ?latitude ;
geo:long ?longitude .
}
GROUP BY ?museum ?latitude ?longitude
SPARQL 结果
产生
museum latitude longitude
http://dbpedia.org/resource/Geffrye_Museum 51.5317 -0.07663
http://dbpedia.org/resource/Geffrye_Museum 51.5317 -0.0762194
幸运的是,这很容易解决。正如中所讨论的这个问题您可以按特征值对结果进行分组,然后对这些值进行采样、最小化、最大化等,以准确获得您想要的结果。例如,如果您想要最大的经度值,您可以使用MAX(?longtude) as ?longitude
在您的 SELECT 中,如以下查询所示,它会生成单个值。
SELECT ?museum ?latitude (MAX(?longitude) as ?longitude)
WHERE {
VALUES ?museum { dbpedia:Geffrye_Museum }
?museum a dbpedia-owl:Museum ;
geo:lat ?latitude ;
geo:long ?longitude .
}
GROUP BY ?museum ?latitude
SPARQL 结果
当然,它假设有一些分组知识?latitude
并最大化?longitude
。分组可能是一个更好的主意?museum
并使用聚合投影来提取其他值,如下所示:
SELECT ?museum (MAX(?latitude) as ?latitude) (MAX(?longitude) as ?longitude)
WHERE {
VALUES ?museum { dbpedia:Geffrye_Museum }
?museum a dbpedia-owl:Museum ;
geo:lat ?latitude ;
geo:long ?longitude .
}
GROUP BY ?museum
SPARQL 结果
对所有变量采用这种方法会产生如下结果:
SELECT DISTINCT ?Museum
(SAMPLE(?name) as ?name)
(SAMPLE(?abstract) as ?abstract)
(SAMPLE(?thumbnail) as ?thumbnail)
(MAX(?latitude) as ?latitude)
(MAX(?longitude) as ?longitude)
(SAMPLE(?photoCollection) as ?photoCollection)
(SAMPLE(?website) as ?website)
(SAMPLE(?homepage) as ?homepage)
(SAMPLE(?wikilink) as ?wikilink)
WHERE {
?Museum a dbpedia-owl:Museum ;
dbpprop:name ?name ;
dbpedia-owl:abstract ?abstract ;
dbpedia-owl:thumbnail ?thumbnail ;
geo:lat ?latitude ;
geo:long ?longitude ;
dbpprop:hasPhotoCollection ?photoCollection ;
dbpprop:website ?website ;
foaf:homepage ?homepage ;
foaf:isPrimaryTopicOf ?wikilink .
FILTER(langMatches(lang(?abstract),"EN"))
FILTER (langMatches(lang(?name),"EN"))
}
GROUP BY ?Museum
LIMIT 20
SPARQL 结果
必须对所有变量使用聚合投影似乎有点尴尬,但它会起作用。但是,您也可以首先在子查询中进行聚合,这将清理变量投影,但代价是子查询。 (子查询不一定会对查询产生负面影响;事实上,它可能是相反的。不过,查询本身有点难以阅读。)
SELECT * WHERE {
# Select museums and a single latitude and longitude for them.
{
SELECT ?Museum (MAX(?longitude) as ?longitude) (MAX(?latitude) as ?latitude) WHERE {
?Museum a dbpedia-owl:Museum ;
geo:lat ?latitude ;
geo:long ?longitude .
}
GROUP BY ?Museum
}
# Get the rest of the properties of the museum.
?Museum dbpprop:name ?name ;
dbpedia-owl:abstract ?abstract ;
dbpedia-owl:thumbnail ?thumbnail ;
dbpprop:hasPhotoCollection ?photoCollection ;
dbpprop:website ?website ;
foaf:homepage ?homepage ;
foaf:isPrimaryTopicOf ?wikilink .
FILTER(langMatches(lang(?abstract),"EN"))
FILTER (langMatches(lang(?name),"EN"))
}
GROUP BY ?Museum
LIMIT 20
SPARQL 结果
最后,由于您需要对名称和地理坐标进行标准化,因此您的最终查询将类似于以下内容。在你的问题中,你只说你想保留“第一个结果”,但结果没有强加特定的顺序,因此不存在唯一的“第一个结果”。有了手头的数据,您可以使用(MIN(?name) as ?name)
你会得到你想要的博物馆研究所的名称,但如果你有一个特定的限制,你需要弄清楚如何使它更具体。
SELECT * WHERE {
# Select museums and a single latitude, longitude, and name for them.
{
SELECT ?Museum
(MIN(?name) as ?name)
(MAX(?longitude) as ?longitude)
(MAX(?latitude) as ?latitude)
WHERE {
?Museum a dbpedia-owl:Museum ;
dbpprop:name ?name ;
geo:lat ?latitude ;
geo:long ?longitude .
FILTER (langMatches(lang(?name),"EN"))
}
GROUP BY ?Museum
}
# Get the rest of the properties of the museum.
?Museum dbpprop:name ?name ;
dbpedia-owl:abstract ?abstract ;
dbpedia-owl:thumbnail ?thumbnail ;
dbpprop:hasPhotoCollection ?photoCollection ;
dbpprop:website ?website ;
foaf:homepage ?homepage ;
foaf:isPrimaryTopicOf ?wikilink .
FILTER(langMatches(lang(?abstract),"EN"))
}
LIMIT 20
SPARQL 结果