Выбор некоторых отличных и не отличимых тегов в SPARQL - PullRequest
12 голосов
/ 22 марта 2011

Я пытаюсь запросить в DBPedia список свойств, относящихся к данному классу в онтологии, но поскольку понятные человеку «метки» не всегда понятны, я также хотел бы привести пример из база данных. Проблема в том, что, хотя я хочу выбрать все отдельные свойства, я хочу только один пример каждого свойства. Вот как выглядит мой запрос без захвата примера:

SELECT DISTINCT ?prop ?title WHERE {
    ?thing ?prop [].
    ?thing a <http://dbpedia.org/ontology/Currency>.
    ?prop rdf:type rdf:Property.
    ?prop rdfs:label ?title.
} ORDER BY DESC(COUNT(DISTINCT ?thing))
LIMIT 100

Если я изменю это в таким образом , я начну получать дублирующиеся значения для? Prop:

SELECT DISTINCT ?prop ?title ?example WHERE {
    ?thing ?prop ?example.
    ?thing a <http://dbpedia.org/ontology/Currency>.
    ?prop rdf:type rdf:Property.
    ?prop rdfs:label ?title.
} ORDER BY DESC(COUNT(DISTINCT ?thing))
LIMIT 100

Я очень новичок в использовании запросов SPARQL и запросов к базе данных в целом, поэтому мне не совсем понятно, как это сделать. В идеале, я хотел бы иметь что-то вроде DISTINCT («prop)» title? Example, который выбирает каждое уникальное значение для prop и возвращает его заголовок и пример.

Ответы [ 3 ]

8 голосов
/ 23 марта 2011

В вашем втором запросе отличное относится к комбинации значений ?prop ?title и ?example. Поэтому вы не получаете дубликатов, например, для следующих двух строк, полученных во втором запросе:

dbpedia2:subunitName    "subunit name "@en  "cent"@en
dbpedia2:subunitName    "subunit name "@en  "centavo"@en

они не являются дубликатами, потому что третья строка ?example имеет два разных значения "cent"@en и "centavo"@en

Один из возможных способов решения этой проблемы - использовать GROUP BY и MIN, чтобы получить только самое низкое ранжированное значение для ?label и ?example, то есть:

SELECT ?prop MIN(?title) MIN(?example) WHERE {
    ?thing ?prop ?example.
    ?thing a <http://dbpedia.org/ontology/Currency>.
    ?prop rdf:type rdf:Property.
    ?prop rdfs:label ?title.
} GROUP BY ?prop
4 голосов
/ 23 марта 2011

Вот альтернативный способ добиться того, что вы хотите с помощью подзапросов:

SELECT ?prop ?title ?example 
WHERE 
{
    ?thing a <http://dbpedia.org/ontology/Currency>.
    ?prop rdf:type rdf:Property.
    { SELECT ?title ?example WHERE { ?thing ?prop ?example . ?prop rdfs:label ?title. } LIMIT 1 }
}
LIMIT 100

Преимущество этого в том, что он соответствует стандартам SPARQL 1.1, как я уже говорил в моем комментарии, упорядочение по агрегату не допускается.по стандарту, так что вы используете специфичное для поставщика расширение, которое ограничит переносимость вашего запроса.

Если вы хотите упорядочить по агрегированному значению способом, который переносим между реализациями SPARQL 1.1, тогда вы должны сначалапроецируй это так:

SELECT ?s (COUNT(?p) AS ?predicates) WHERE
{
  ?s ?p ?o
} GROUP BY ?s ORDER BY DESC(?predicates)
1 голос
/ 09 ноября 2018

Если вам не нравится пример, но вам важна скорость, SAMPLE может быть намного быстрее, чем GROUP BY

SELECT ?prop (SAMPLE(?title) AS ?title) (SAMPLE(?example) AS ?example) 
WHERE {
    ?thing ?prop ?example.
    ?thing a <http://dbpedia.org/ontology/Currency>.
    ?prop rdf:type rdf:Property.
    ?prop rdfs:label ?title.
} LIMIT 100

Вероятно, вы не заметите разницу в dbpedia, поскольку она кэширует результаты запросов, но я заметил огромную разницу при использовании других конечных точек.

Я столкнулся с той же проблемой, которая возникла при создании службы автозаполнения, которая запрашивает несколько конечных точек sparql. Мне нужно было найти одну ссылку, относящуюся к поисковому запросу, сама ссылка на которую не очень важна, но скорость запроса была очень важной.

...