Сначала рассмотрим один случай. В случае 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
person
Joshua Taylor
schedule
18.06.2013
foaf:name
, которые могут быть полезны. тебе. - person Joshua Taylor   schedule 18.06.2013VALUES ?Museum { dbpedia:Geffrye_Museum }
в свой запрос, это ограничит значение?Museum
доdbpedia:Geffrye_Museum
, поэтому будет показан только дублированный результат. - person Joshua Taylor   schedule 18.06.2013