SPARQL выбирает необязательный язык
У меня есть несколько троек, которые выглядят так:
test:thing rdfs:label "Non-Language Label"
test:thing rdfs:label "English Label"@en
test:thing rdfs:label "French Label"@fr
Я хотел бы создать запрос sparql, который дает мне "Non-Language Label" и "French Label", если таковой существует.
Я пробовал это и не работал:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT ?label ?preferredLabel
WHERE {
test:thing rdfs:label ?label
OPTIONAL {
test:thing rdfs:label ?preferredLabel .
FILTER (regex(str(?preferredLabel), '(^|\\\\W)fr', 'i'))
}
}
Спасибо заранее!
Ответы
Ответ 1
Я не понимаю, зачем вам OPTIONAL
здесь вообще. Ян-запрос терпит неудачу, потому что между внешним шаблоном и опцией нет общей переменной, поэтому вы пытаетесь вычислить кросс-произведение каждой метки для test:thing
с каждым не-французским обозначенным test:thing
, который может быть огромным и почему запрос процессор не работает.
Вам просто нужно что-то вроде следующего, если я не понял ваш вопрос
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT ?label
WHERE
{
test:thing rdfs:label ?label
FILTER(LANG(?label) = "" || LANGMATCHES(LANG(?label), "fr"))
}
Если вам нужны два ярлыка отдельно, вы можете сделать что-то вроде:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT ?label ?preferredLabel
WHERE
{
{
test:thing rdfs:label ?label . FILTER(LANG(?label) = "")
}
UNION
{
test:thing rdfs:label ?preferredLabel . FILTER(LANGMATCHES(LANG(?label), "fr"))
}
}
Ответ 2
Самый простой способ проверить язык литералов - использовать функцию lang(). Используя это, ваш запрос может быть записан как:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX test: <http://test#>
SELECT ?label ?preferredLabel
WHERE {
test:thing rdfs:label ?label
OPTIONAL {
test:thing rdfs:label ?preferredLabel .
FILTER (lang(?preferredLabel) = "" || lang(?preferredLabel) = "fr")
}
}
Ответ 3
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT ?uri ?label ?preferredLabel
WHERE
{
{
?uri rdfs:label ?label . FILTER(LANG(?label) = "" && regex(str(?label), '(^|\\\\W)fr', 'i'))
}
UNION
{
?uri rdfs:label ?preferredLabel . FILTER(LANG(?preferredLabel) = "fr" && regex(str(?preferredLabel), '(^|\\\\W)fr', 'i'))
}
}