Один и тот же запрос на Sparql дает разные результаты

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

Рассмотрим этот запрос, который я отправляю в http://live.dbpedia.org/sparql (конечная точка Virtuoso) и в результате получите 34 тройки. Результат Sparql

SELECT  ?pred ?obj
    WHERE { 
           <http://dbpedia.org/resource/Johann_Sebastian_Bach> ?pred ?obj
        FILTER((langMatches(lang(?obj), "")) ||
                      (langMatches(lang(?obj), "EN"))
          )
    }

Затем я использовал тот же запрос в коде на Python:

import rdflib
import rdfextras
rdfextras.registerplugins()

g=rdflib.Graph()
g.parse("http://dbpedia.org/resource/Johann_Sebastian_Bach")

PREFIX = """
                PREFIX dbp: <http://dbpedia.org/resource/>
"""

query = """
                SELECT ?pred ?obj
                    WHERE {dbp:Johann_Sebastian_Bach ?pred ?obj
                        FILTER( (langMatches(lang(?obj), "")) ||
                                (langMatches(lang(?obj), "EN")))}
"""
query = PREFIX + query
result_set = g.query(query)
print len(result_set)

На этот раз у меня всего 27 троек! https://dl.dropboxusercontent.com/u/22943656/result.txt

Я подумал, что это может быть связано с сайтом dbpedia. Я повторял эти запросы несколько раз и всегда получал одну и ту же разницу. Поэтому я загрузил файл RDF, чтобы протестировать его локально, и использовал программное обеспечение Protége для моделирования конечной точки Virtuoso. Несмотря на это, у меня все еще есть разные результаты из sparql, представленного в Protége и Python, 31 и 27. Есть ли какое-нибудь объяснение этой разнице? И как я могу получить одинаковый результат в обоих?


person Marcelo    schedule 26.11.2013    source источник
comment
Какие утверждения в одном, а в другом нет?   -  person AndyS    schedule 26.11.2013
comment
Я думаю, что их не нужно объявлять в конечной точке Virtuoso, потому что она запрашивает в DBpedia. Но даже если я удалю префикс по умолчанию (PREFIX rdf: ‹w3. org / 1999/02/22-rdf-syntax-ns # ›, PREFIX owl: ‹w3.org/2002/07/owl#›, PREFIX xsd: ‹w3.org/2001/XMLSchema# ›, PREFIX rdfs: ‹w3.org/2000/01/rdf-schema# ›), это не меняет результат в python.   -  person Marcelo    schedule 26.11.2013
comment
Я редактировал код на питоне   -  person Marcelo    schedule 26.11.2013
comment
Какой 31 результат вы получите? Какие 27 результатов вы получите?   -  person Joshua Taylor    schedule 26.11.2013
comment
Есть ли у вас основания полагать, что данные из live.dbpedia.org/sparql (т. Е. Из DBpedia Live) будет таким же, как данные в основной DBpedia (что dbpedia.org/resource/Johann_Sebastian_Bach дает)? Вы запрашиваете разные наборы данных.   -  person Joshua Taylor    schedule 26.11.2013
comment
lang возвращает "" для литералов, у которых нет языкового тега. Я не уверен, как langMatches обрабатывает "", но что произойдет, если вы измените langMatches(lang(?obj),"") на lang(?obj) = ""?   -  person Joshua Taylor    schedule 27.11.2013
comment
В более ранних версиях RDFlib была ошибка, когда lang(x) для буквального x, не имеющего языкового тега, возвращал None вместо "". Он упоминается в этой проблеме.   -  person Joshua Taylor    schedule 27.11.2013
comment
Пытаясь понять, что здесь должно произойти, я задал вопрос на answers.semanticweb.com, langMatches (,) true или false?   -  person Joshua Taylor    schedule 27.11.2013
comment
Я знаю, что у нас есть рабочее решение, но какую версию rdflib вы используете? Более поздняя версия включает в себя запросы SPARQL в код, поэтому вам не нужно импортировать rdfextras, но у меня возникают некоторые проблемы при попытке запустить ваш код в более поздних версиях rdflib.   -  person Joshua Taylor    schedule 27.11.2013
comment
Я использую версию 4.0.1, а Python - 2.7.2. Да ты прав! Я тестировал без rdfextras, и он работает.   -  person Marcelo    schedule 28.11.2013


Ответы (1)


Поскольку вопрос написан, есть несколько возможных проблем. Судя по комментариям, первая из описанных здесь проблем (о lang, langMatches и т. Д.) Кажется тем, с чем вы на самом деле сталкиваетесь, но я оставлю описания других возможных проблем, на случай, если кто-то другой сочтет их полезными.

lang, langMatches и пустая строка

lang должен возвращать "" для литералов без языковых тегов. Согласно RFC 4647 2.1 языковые теги определяются следующим образом:

2.1. Базовый языковой диапазон

«Базовый языковой диапазон» имеет тот же синтаксис, что и языковой тег [RFC3066], или представляет собой одиночный символ «*». Базовый диапазон языков был первоначально описан в HTTP / 1.1 [RFC2616] и позже [RFC3066]. Он определяется следующим ABNF [RFC4234]:

language-range   = (1*8ALPHA *("-" 1*8alphanum)) / "*"
alphanum         = ALPHA / DIGIT

Это означает, что "" на самом деле не является юридическим языковым тегом. Как отметил Джин Брукстра в answer.semanticweb .com, в рекомендации SPARQL говорится:

17.2 Оценка фильтра

SPARQL предоставляет подмножество функций и операторов, определенных в XQuery Operator Mapping. Раздел 2.2.3 «Обработка выражений» XQuery 1.0 описывает вызов функций XPath. Следующие правила учитывают различия в моделях данных и выполнения между XQuery и SPARQL:…

  • Функции, вызываемые с аргументом неправильного типа, вызовут ошибку типа. Эффективные аргументы логического значения (помеченные «xsd: boolean (EBV)» в таблице сопоставления операторов ниже) приводятся к xsd: boolean с использованием правил EBV в разделе 17.2.2.

Поскольку "" не является тегом юридического языка, его можно рассматривать как «аргумент неправильного типа, [который] вызовет ошибку типа». В этом случае вызов langMatches приведет к ошибке, и эта ошибка будет рассматриваться как ложная в выражении filter. Даже если по этой причине он не возвращает false, RFC 4647 3.3.1, который описывает, как сравниваются языковые теги и диапазоны, не говорит точно, что должно происходить при сравнении, так как предполагает допустимые языковые теги:

Базовая фильтрация сравнивает базовые языковые диапазоны с языковыми тегами. Каждый базовый языковой диапазон в списке приоритетов языков рассматривается по очереди в соответствии с приоритетом. Языковой диапазон соответствует определенному языковому тегу, если при сравнении без учета регистра он в точности совпадает с тегом, или если он в точности равен префиксу тега, так что первый символ, следующий за префиксом, равен "-" . Например, языковой диапазон «de-de» (немецкий, используемый в Германии) соответствует языковому тегу «de-DE-1996» (немецкий, используемый в Германии, орфография 1996 года), но не языковым тегам «de- Deva »(немецкий, написанный письмом Деванагари) или« de-Latn-DE »(немецкий, латинский шрифт, используемый в Германии).

Основываясь на ваших комментариях и моих локальных экспериментах, кажется, что langMatches(lang(?obj),"") для литералов без языковых тегов (на самом деле, langMatches("","")) возвращает true в Virtuoso (поскольку он установлен в DBpedia), ARQ Jena (из моих экспериментов) и Proégé (из наших эксперименты), и он возвращает false (или ошибку, которая была приведена к false) в RDFlib.

В любом случае, поскольку lang определен для возврата "" для литералов без языкового тега, вы сможете надежно включить их в свои результаты, изменив langMatches(lang(?obj),"") на lang(?obj) = "".

Проблемы с данными, которые вы используете

Вы запрашиваете разные данные. Данные, которые вы загружаете из

взято из DBpedia, но когда вы запускаете запрос к

вы запускаете его в DBpedia Live, который может иметь другие данные. Если вы запустите этот запрос на конечной точке DBpedia Live и на конечной точке DBpedia, вы получите другое количество результатов:

SELECT count(*) WHERE { 
  dbpedia:Johann_Sebastian_Bach ?pred ?obj
  FILTER( langMatches(lang(?obj), "")  || langMatches(lang(?obj), "EN" ) )
}

Результаты DBpedia Live 31
результаты DBpedia 34

Проблемы с distinct

Другая возможная проблема, хотя она, похоже, не та, с которой вы столкнулись, заключается в том, что ваш второй запрос имеет модификатор distinct, а ваш первый - нет. Это означает, что ваш второй запрос может легко дать меньше результатов, чем первый.

Если вы запустите этот запрос к конечной точке DBpedia SPARQL, вы должны получить 34 результата, независимо от того, используете ли вы модификаторы distinct, и это число, которое вы должны получить, если загрузите данные и выполните тот же запрос к ним.

select ?pred ?obj where { 
  dbpedia:Johann_Sebastian_Bach ?pred ?obj
  filter( langMatches(lang(?obj), "") || langMatches(lang(?obj), "EN") )
}

результаты SPARQL

person Joshua Taylor    schedule 26.11.2013
comment
Спасибо, Джошуа. Я удалил модификатор DISTINCT, и, как вы сказали, результат не изменился. Мой главный вопрос: почему один и тот же запрос, используемый в python и sparql (protege), работал с моими локальными данными rdf, по-прежнему дает мне разные результаты? - person Marcelo; 27.11.2013
comment
Я понял, что эти различия связаны с этими тройками: dbpedia.org/ontology/birthDate 1685- 03-21 dbpedia.org/ontology/deathDate 1750-07-28 dbpedia.org/ontology/wikiPageID 9906294 dbpedia.org/ontology/wikiPageRevisionID 546793436 dbpedia.org/property/dateOfBirth 21 dbpedia.org/property/dateOfDeath 28 dbpedia.org/property/id 24 - person Marcelo; 27.11.2013
comment
@ user2725174 Вы все еще выполняете первый запрос к DBpedia Live? DBpedia Live - это не те же данные, что и версия DBpedia, которую вы получаете из dbpedia. org / resource * `. Неудивительно, что вы получаете разные результаты, если запрашиваете разные данные. Как я спросил в комментарии к вопросу, обновите свой вопрос, указав фактические разные результаты, которые вы получаете. - person Joshua Taylor; 27.11.2013
comment
у всех есть числа в предметах! Для ясности, я получаю меньше троек при запуске запроса на python. Не могли бы вы это объяснить? Есть ли способ получить такой же результат на Python? - person Marcelo; 27.11.2013
comment
последние комментарии были основаны на данных в формате rdf, загруженных с DBpedia. Когда я запускаю запрос в sparql (protege) и python, они разные - person Marcelo; 27.11.2013
comment
Конечно, у них есть числа в объектах, что и следовало ожидать из-за вашего запроса. Это не сюрприз, правда? Язык такого литерала будет соответствовать "". - person Joshua Taylor; 27.11.2013
comment
@ user2725174 В вашем вопросе ничего не говорится о Protégé, только о Python и веб-клиенте. Мы не сможем определить, в чем заключаются различия, если мы не сможем увидеть какие различия вы получите. Если вы не отредактируете свой вопрос, чтобы показать, какие результаты вы получаете в одной системе, а какие - в другой, мы не сможем оказать какую-либо помощь. - person Joshua Taylor; 27.11.2013
comment
Да, но эти числа есть только в запросе, использующем протеже. Когда я использую python, они не извлекаются. Вот и отличия! - person Marcelo; 27.11.2013
comment
@ user2725174 Это первый раз, когда вы прояснили, в чем различия. Вы получаете литералы типа данных, у которых нет языкового тега, когда вы запускаете запрос в Python, но с другими механизмами запросов, которые у вас есть. Было бы намного проще, если бы вы могли показать эти результаты в вопросе; тогда кто-то другой мог бы понять, что происходило до этого. Теперь все сводится к следующему: этот запрос… выбирает нестроковые литералы как ?obj, когда я использую Protégé или DBpedia's Virtuoso, но они не выбираются при использовании Python rdflib. Почему? - person Joshua Taylor; 27.11.2013
comment
@ user2725174 У меня пока нет на это ответа, но это гораздо более конкретный и конкретный вопрос. - person Joshua Taylor; 27.11.2013
comment
@ user2725174 В комментарии к вопросу я добавил возможное решение. Пожалуйста, взгляните на это и попробуйте, и дайте мне знать, что происходит. - person Joshua Taylor; 27.11.2013
comment
Еще раз спасибо, Джошуа! Просто чтобы вы знали, проблема была в langMatches (lang (? Obj),). Когда я изменил его на lang (? Obj) =, все заработало! - person Marcelo; 27.11.2013