DBpedia SPARQL 查询返回多条重复记录

Nir*_*att 1 sparql dbpedia

我对 SPARQL 很陌生,并且对它现有的多种语法标准感到困惑。我正在努力使用以下查询从 DBpedia 获取唯一数据:

SELECT DISTINCT ?Museum, ?name, ?abstract, ?thumbnail, ?latitude,
   ?longitude, ?photoCollection, ?website, ?homepage, ?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"))
}
LIMIT 20
Run Code Online (Sandbox Code Playgroud)

SPARQL 结果

因为任何人都可以看到,针对这些项目Geffrye_Museum,并Institute_for_Museum_Research重复了结果,因为Institute_for_Museum_Research有它的名字两个不同的值,并 Geffrye_Museum有两个经度值。在这两种重复情况下,我希望丢弃第二个值;即,Geffrye_Museum经度值-0.0762194必须被忽略,而Institute_for_Museum_Research名称值"Institut für Museumsforschung"@en必须被忽略。

请注意,我已经对我想要的字段应用过滤,这只是 DBpedia 中我想在查询级别本身处理的大量数据。那么当同一列有多个值时,如何让 DBpedia 只返回第一个值?

Jos*_*lor 6

我们先来看一个案例。在 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
Run Code Online (Sandbox Code Playgroud)

SPARQL 结果

产生

museum                                     latitude longitude
http://dbpedia.org/resource/Geffrye_Museum 51.5317  -0.07663
http://dbpedia.org/resource/Geffrye_Museum 51.5317  -0.0762194
Run Code Online (Sandbox Code Playgroud)

幸运的是,这很容易补救。正如在这个问题中所讨论的,您可以按特征值对结果进行分组,然后对这些值进行采样、最小化、最大化等,以精确获得您想要的结果。例如,如果您想要最大的经度值,您可以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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

SPARQL 结果