【发布时间】:2015-04-09 10:34:05
【问题描述】:
几年前我学习了一些语义技术,包括 RDF 和 SPARQL,然后我有一段时间没有机会使用它们。现在我开始了一个使用 OpenRDF 2.8.0 作为语义存储的新项目,我正在恢复我的知识,即使我有一些被遗忘的东西要恢复。
特别是,在过去的几天里,我在正确理解 SPARQL 中的 FILTER NOT EXIST 构造时遇到了一些麻烦。
问题:我有一个从 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,因为我将分别获得“Doris Day”和“Howard Keel”。我必须检索示例 #3 “Pat Metheny & Anna Maria Jopek”,因为我无能为力。当然,我也想找回“René Marie”。
我已经用这个 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 的语句不起作用。也就是说,他们没有找到“René Marie”等物品。
虽然我对使用 MINUS 找到的最短解决方案感到满意,但我不明白为什么旧解决方案不起作用这一事实。显然我错过了FILTER NOT EXISTS 的一些要点,这可能对其他情况有用。
欢迎任何帮助。
【问题讨论】:
-
你的一个 cmets 说“没有与单身人士合作的组”——是否应该检查合作者(?any1 的值)实际上是单身人士人,即不是一个群体?
-
约书亚,好问题。在与我的音乐收藏相关的数据中,我没有看到与组相关的组,但我当然没有探索整个存储库。我觉得没关系。这个想法是,如果有一个 rel:collaborationWith 它可以是任何东西,最终是一个协作链,将有一个与任何东西不再相关的最终项目。