SPARQL: объединять и исключать фильтры регулярных выражений
Я хочу отфильтровать свой запрос SPARQL по определенным ключевым словам, в то же время исключая другие ключевые слова. Я думал, что это может быть легко достигнуто с FILTER (regex(str(?var),"includedKeyword","i") && !regex(str(?var),"excludedKeyword","i"))
, Работает без "!" состояние, но не с. Я также отделил операторы FILTER, но бесполезно.
Я использовал этот запрос на http://europeana.ontotext.com/:
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX edm: <http://www.europeana.eu/schemas/edm/>
PREFIX ore: <http://www.openarchives.org/ore/terms/>
SELECT DISTINCT ?CHO
WHERE {
?proxy dc:subject ?subject .
FILTER ( regex(str(?subject),"gemälde","i") && !regex(str(?subject),"Fotografie","i") )
?proxy edm:type "IMAGE" .
?proxy ore:proxyFor ?CHO.
?agg edm:aggregatedCHO ?CHO; edm:country "germany".
}
Но я всегда получаю результат в первой строке с заголовком "Gemäldegalerie", в котором есть dc:subject "Fotografie" (тот, который я хочу исключить). Я думаю, что проблема заключается в том, что один объект из базы данных Europeana может иметь более одного свойства dc:subject, поэтому, возможно, он ищет только одно из этих свойств, игнорируя другие.
Есть идеи? Был бы очень благодарен!
1 ответ
Проблема в том, что ваш комбинированный фильтр проверяет одинаковую привязку ?subject
, Так что это успешно, если хотя бы одно значение ?subject
соответствует обоим условиям (что почти всегда верно, поскольку строка "Gemäldegalerie", например, соответствует вашему первому регулярному выражению и не соответствует второму).
Поэтому для отрицательного условия вам нужно сформулировать что-то, что проверяет все возможные значения, а не только одно конкретное значение. Вы можете сделать это с помощью SPARQL NOT EXISTS
функция, например, так:
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX edm: <http://www.europeana.eu/schemas/edm/>
PREFIX ore: <http://www.openarchives.org/ore/terms/>
SELECT DISTINCT ?CHO
WHERE {
?proxy edm:type "IMAGE" .
?proxy ore:proxyFor ?CHO.
?agg edm:aggregatedCHO ?CHO; edm:country "germany".
?proxy dc:subject ?subject .
FILTER(regex(str(?subject),"gemälde","i"))
FILTER NOT EXISTS {
?proxy dc:subject ?otherSubject.
FILTER(regex(str(?otherSubject),"Fotografie","i"))
}
}
Как в стороне: так как вы делаете проверки регулярных выражений, а теперь комбинируете их с NOT EXISTS
оператор, это может стать очень дорогим для обработчика запросов довольно быстро. Возможно, вы захотите подумать об альтернативных способах формулирования вашего запроса (например, использование точной строки темы для включения или исключения для исключения регулярного выражения) или даже взглянуть на некоторые нестандартные расширения, которые может предоставить конечная точка SPARQL (OWLIM Например, хранилище, в котором работает конечная точка Europeana, поддерживает различные расширения полнотекстового поиска, хотя я не уверен, что они включены в конечной точке Europeana).