2013-06-18 231 views
1

我對SPARQL非常陌生,也對現有的各種語法標準感到困惑。 我奮力用下面的查詢來從DBpedia中唯一的數據:DBpedia SPARQL查詢返回多條記錄和重複記錄

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 

SPARQL results

因爲任何人都可以看到,重複在結果Geffrye_MuseumInstitute_for_Museum_Research項,因爲Institute_for_Museum_Research有兩個不同的值了名稱和Geffrye_Museum有兩個經度值。在這兩個重複的情況下,我希望丟棄第二個值;即對於Geffrye_Museum,經度值-0.0762194必須被忽略,並且對於Institute_for_Museum_Research,名稱值"Institut für Museumsforschung"@en必須被忽略。

請注意,我已經在爲我想要的字段應用過濾,並且這只是我在查詢級本身處理的DBpedia中豐富的數據。那麼如何讓DBpedia在同一列有多個值時僅返回第一個值?

+0

有一個[最近的問題(http://stackoverflow.com/q/17129225/1281433)有關如何避免因,例如,多個'FOAF出現重複的結果:名稱被定義爲可能對你有用。 –

+0

此外,作爲創建最小工作示例的註釋,如果您向查詢中添加了'VALUES?Museum {dbpedia:Geffrye_Museum}',它會將'?Museum'的值限制爲'dbpedia:Geffrye_Museum',因此只有重複的結果被顯示。 –

回答

3

讓我們先看一個案例。在葛弗萊的情況下,重複的結果發生,因爲多個經度存在於數據,如下面的查詢演示:

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 results

產生

museum          latitude longitude 
http://dbpedia.org/resource/Geffrye_Museum 51.5317 -0.07663 
http://dbpedia.org/resource/Geffrye_Museum 51.5317 -0.0762194 

幸運的是,這是容易彌補。正如在this question中所討論的那樣,您可以將結果按其特徵值進行分組,然後對這些值進行採樣,最小化,最大化等,以獲得您想要的結果。例如,如果您想要最大的經度值,您可以在SELECT中使用MAX(?longtude) as ?longitude,如下面的查詢所示,該查詢生成單個值。

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 results

當然,通過?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 results

採取這種方法,所有變量的產生是這樣的:

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 results

這似乎有點尷尬不得不使用聚合projecti在所有的變量上,但它會工作。但是,您也可以先在子查詢中進行聚合,然後以子查詢爲代價來清理變量投影。 (子查詢不一定會對查詢產生負面影響,實際上它可能恰恰相反,但查詢本身有點難以閱讀。)

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 results

最後,因爲你需要在標準化名稱以及地理座標,最終的查詢將會像下面這樣。在你的問題中,你只是說你想保留「第一結果」,但沒有特別的結果強制性規定,所以沒有唯一的「第一結果」。有了這些數據,你可以使用(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 results

+1

你真棒! –