dbpediasparql查询返回多个和重复的记录

dbpediasparql查询返回多个和重复的记录,sparql,dbpedia,Sparql,Dbpedia,我对SPARQL非常陌生,并且对它现有的多种语法标准感到困惑。 我正在努力使用以下查询从DBpedia获取唯一数据: SELECT DISTINCT ?Museum, ?name, ?abstract, ?thumbnail, ?latitude, ?longitude, ?photoCollection, ?website, ?homepage, ?wikilink WHERE { ?Museum a dbpedia-owl:Museum ; dbpprop:

我对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
任何人都可以看到,Geffrye_Museum和Institute_for_Museum_Research的条目在结果中重复出现,因为Institute_for_Museum_Research有两个不同的名称值,Geffrye_Museum有两个经度值。在这两种重复的情况下,我希望第二个值被丢弃;i、 例如,对于Geffrye_博物馆,经度值-0.0762194必须忽略,对于Institute_for_Museum_Research,名称值Institute fürMuseumsforschung@en必须忽略这一点


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

让我们先看一个案例。对于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
产生

museum                                     latitude longitude
http://dbpedia.org/resource/Geffrye_Museum 51.5317  -0.07663
http://dbpedia.org/resource/Geffrye_Museum 51.5317  -0.0762194
幸运的是,这很容易补救。如中所述,您可以根据其特征值对结果进行分组,然后对这些值进行采样、最小化、最大化等,以精确地获得所需的结果。例如,如果希望获得最大值的经度,可以在SELECT中使用MAX?longtude作为经度,如以下查询中所示,该查询生成一个值

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
当然,它假定有一点知识可以按纬度分组,并最大限度地超越经度。最好是按博物馆分组,然后使用聚合投影提取其他值,如:

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
对所有变量采用这种方法会产生如下结果:

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
在所有变量上使用聚合投影似乎有点尴尬,但它会起作用。但是,您也可以先在子查询中进行聚合,这将以子查询为代价清理变量投影。子查询不一定对查询有负面影响;事实上,情况可能恰恰相反。不过,查询本身有点难读

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
最后,由于需要对名称和地理坐标进行规范化,因此最终的查询如下所示。在你的问题中,你只说你想保留“第一个结果”,但没有对结果施加特定的顺序,因此没有唯一的“第一个结果”。有了手头的数据,你可以使用MIN?name作为?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

让我们先看一个案例。对于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
产生

museum                                     latitude longitude
http://dbpedia.org/resource/Geffrye_Museum 51.5317  -0.07663
http://dbpedia.org/resource/Geffrye_Museum 51.5317  -0.0762194
幸运的是,这很容易补救。如中所述,您可以根据其特征值对结果进行分组,然后对这些值进行采样、最小化、最大化等,以精确地获得所需的结果。例如,如果希望获得最大值的经度,可以在SELECT中使用MAX?longtude作为经度,如以下查询中所示,该查询生成一个值

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
当然,它假定有一点知识可以按纬度分组,并最大限度地超越经度。最好是按博物馆分组,然后使用聚合投影提取其他值,如:

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
对所有变量采用这种方法会产生如下结果:

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
在所有变量上使用聚合投影似乎有点尴尬,但它会起作用。但是,您也可以先在子查询中进行聚合,这将以子查询为代价清理变量投影。子查询不一定对查询有负面影响;事实上,情况可能恰恰相反。不过,查询本身有点难读

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
最后,由于需要对名称和地理坐标进行规范化,因此最终的查询如下所示。在你的问题中,你只说你想保留“第一个结果”,但没有对结果施加特定的顺序,因此没有唯一的“第一个结果”。有了手头的数据,你可以使用MIN?name作为?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

有一个关于如何避免因定义多个foaf:名称而产生重复结果的问题,例如可能对您有用。此外,如果您添加值,请注意创建最少的工作示例?Museum{dbpedia:Geffrye_Museum}
在您的查询中,它将?Museum的值限制为dbpedia:Geffrye_Museum,因此只显示重复的结果。关于如何避免因定义多个可能对您有用的foaf:名称而产生重复结果,有一个问题。另外,作为创建最小工作示例的注意事项,如果您添加值?Museum{dbpedia:Geffrye_Museum}对于您的查询,它将?Museum的值限制为dbpedia:Geffrye_Museum,因此只显示重复的结果。