Несколько лет назад я изучил некоторые семантические технологии, включая RDF и SPARQL, после чего у меня не было шансов работать с ними некоторое время. Теперь я начал новый проект, который использует OpenRDF 2.8.0 в качестве семантического хранилища, и я возобновляю свои знания, хотя у меня есть некоторые забытые вещи для восстановления.О UNION и FILTER NOT EXISTS в SPARQL (OpenRDF 2.8.0)
В частности, в прошлые дни у меня возникли проблемы с правильной деинсталляцией конструкции FILTER NOT EXIST в SPARQL.
Проблема: у меня есть семантический магазин, импортированный из DbTune.org (он-томы музыки). mo:MusicArtist
, задумана как foaf:maker
из более mo:Track
, может присутствовать в четырех сценариев (я только листинг соответствующие заявления):
<http://dbtune.org/musicbrainz/resource/artist/013c8e5b-d72a-4cd3-8dee-6c64d6125823> a mo:MusicArtist ;
vocab:artist_type "1"^^xs:short ;
rdfs:label "Edvard Grieg" .
<http://dbtune.org/musicbrainz/resource/artist/032df978-9130-490e-8857-0c9ef231fae8> a mo:MusicArtist ;
vocab:artist_type "2"^^xs:short ;
rel:collaboratesWith <http://dbtune.org/musicbrainz/resource/artist/3db5dfb1-1b91-4038-8268-ae04d15b6a3e> , <http://dbtune.org/musicbrainz/resource/artist/d78afc01-f918-440c-89fc-9d546a3ba4ac> ;
rdfs:label "Doris Day & Howard Keel".
<http://dbtune.org/musicbrainz/resource/artist/1645f335-2367-427d-8e2d-ad206946a8eb> a mo:MusicArtist ;
vocab:artist_type "2"^^xs:short ;
rdfs:label "Pat Metheny & Anna Maria Jopek".
<http://dbtune.org/musicbrainz/resource/artist/12822d4f-4607-4f1d-ab16-d6bacc27cafe> a mo:MusicArtist ;
rdfs:label "René Marie".
Из того, что я понимаю, vocab:artist_type
является 1
для отдельных художников (пример # 1) и 2
для групп сотрудничества (примеры № 2 и № 3). В этом случае может быть несколько операторов rel:collaboratesWith
, которые указывают на описание отдельных членов группы или совместной работы (пример № 2). В некоторых случаях отсутствует инструкция vocab:artist_type
(пример № 4).
Теперь я хочу извлечь всех художников как единичные объекты, где это возможно. Я имею в виду, я не хочу извлекать пример №2, потому что я получу «Дорис Дэй» и «Говард Кил» отдельно. Мне нужно извлечь пример № 3 «Pat Metheny & Anna Maria Jopek», потому что я ничего не могу сделать. Конечно, я также хочу получить «Рене Мари».
Я решил эту проблему удовлетворительным образом с этим SPARQL:
SELECT *
WHERE
{
?artist a mo:MusicArtist.
?artist rdfs:label ?label.
MINUS
{
?artist vocab:artist_type "2"^^xs:short.
?artist rel:collaboratesWith ?any1 .
}
}
ORDER BY ?label
Это имеет смысл, и это выглядит, как будто это читаемое («извлечь все mo:MusicArtist
элементов минус тех, которые сотрудничество с отдельными членами перечисленных»).
Я не нашел решение немедленно. Я сначала подумал, укладывание три отдельных случаев, с UNION
:
SELECT *
WHERE
{
?artist a mo:MusicArtist.
?artist rdfs:label ?label.
# Single artists
{
?artist vocab:artist_type "1"^^xs:short.
}
UNION
# Groups for which there is no defined collaboration with single persons
{
?artist vocab:artist_type "2"^^xs:short.
FILTER NOT EXISTS
{
?artist rel:collaboratesWith ?any1
}
}
UNION
# Some artists don't have this attribute
{
FILTER NOT EXISTS
{
?artist vocab:artist_type ?any2
}
}
}
ORDER BY ?label
Я обнаружил, что третьи UNION
заявления, те, которые должны добавить mo:MusicArtist
элементов без vocab:artist_type
, не работало. То есть, они не нашли такие предметы, как «Рене Мари».
В то время как я удовлетворен самым коротким решением, которое я нашел с MINUS
, я не согласен с тем, что не понимаю, почему старое решение не сработало. Ясно, что я пропустил какой-то момент с FILTER NOT EXISTS
, который может быть полезен для другого случая.
Любая помощь приветствуется.
Один из ваших комментариев говорит «Группы, для которых не существует определенного сотрудничества с отдельными лицами» --- там должен быть какой-либо проверки, что сотрудник (значение? Any1) на самом деле один человек, т. е. не группа? –
Joshua, хорошо вопрос. Я не видел групп, связанных с группами, в данных, связанных с моей музыкальной коллекцией, но, конечно, я не исследовал весь репозиторий. Я думаю, это не имеет значения. Идея состоит в том, что если есть rel: collaborationWith это может быть что угодно, и в конечном итоге цепочка сотрудничества, будет конечный элемент, который больше не связан ни с чем. –