将 freebase MQL 转换为 SPARQL
converting freebase MQL to SPARQL
以下 freebase MQL 找到 5 位艺术家和每位艺术家的 50 张专辑。
[{
"type" : "/music/artist",
"name":null,
"album" : [{
"name" : null,
"count":null,
"limit":50
}],
"limit":5
}]
第一次尝试 - 没有子查询
我可以这样写 SPARQL:
SELECT ?artist ?album
WHERE
{
?artist :type :/music/artist .
?artist :album ?album
}
LIMIT n
但是,我不知道应该指定多少 n
,因为据我所知,SPARQL 没有层次结构。
第二次尝试 - 使用子查询(不确定是否正常工作)
以下子查询看起来有效。
SELECT ?artist ?album
WHERE
{
?artist :album ?album .
{
SELECT ?artist
WHERE
{
?artist :type :/music/artist
}
LIMIT k
}
}
LIMIT n
但我不知道如何指定k
、n
来为每5位艺术家获得50张专辑。
一些具有端点的数据
- SPARQL 端点:http://dbpedia.org/sparql
谁能写出 SPARQL
打印 5 位艺术家和他们的 5 幅画作?
下面的查询打印了艺术家和他们的绘画,但没有 LIMIT
结果。
PREFIX dbpedia-owl:<http://dbpedia.org/ontology/>
PREFIX prop:<http://dbpedia.org/property/>
SELECT ?painting ?artist
WHERE
{
?painting prop:artist ?artist .
{
SELECT ?artist
{
?artist rdf:type dbpedia-owl:Artist.
}
}
}
谢谢。
根据你想要得到的结果,这涉及某种嵌套的相关子查询处理,这在单个 SPARQL 查询中是不直接可行的(至少在我的理解中,但如果可能的话,我完全在 ;) ):
Due to the bottom-up nature of SPARQL query evaluation, the subqueries
are evaluated logically first, and the results are projected up to the
outer query.
在与子查询的连接评估之后应用的第二个限制子句,它只会限制外部查询的结果数。
在第二次尝试的子查询中使用 LIMIT k (k=5) 子句将有效地 return 您需要的 5 位艺术家,但将 n 限制为 50 只会强制专辑结果(外部查询)所有这 5 位艺术家的全球 50 个结果,而不是您想要的 50 个/艺术家。将查询由内而外翻转会给您类似的效果。
编辑:
一个可能的解决方案是为所有 artists/albums 构建一个子查询,并将子查询限制在(以某种方式)订购的专辑数量低于 50 的地方(这里使用专辑 title IRI 排序)
PREFIX dbpedia-owl:<http://dbpedia.org/ontology/>
PREFIX prop:<http://dbpedia.org/property/>
SELECT ?artist ?outputAlbum
WHERE
{
{
SELECT ?artist (MAX(str(?album1)) as ?maxedAlbum)
WHERE {
?album1 prop:artist ?artist .
?album2 prop:artist ?artist .
FILTER (str(?album2) < str(?album1))
}
GROUP BY ?artist
HAVING count(?album2)<= 50
LIMIT 5
}
?outputAlbum prop:artist ?artist .
FILTER (str(?outputAlbum) < str(?maxedAlbum))
}
编辑 2:最后一个查询将是天真的方法,但似乎在 dbpedia 端点(如下所示)上有一些推论(未知的 re"gime)。更多精确查询将需要更多的过滤器和不同的子句——我在输出中添加了不同的和全局的计数以显示某处仍有一些推论):
PREFIX dbpedia-owl:<http://dbpedia.org/ontology/>
PREFIX prop:<http://dbpedia.org/property/>
SELECT ?artist ?outputAlbum ?maxedCount ?inferredCrossJoinCount
WHERE
{
{
SELECT ?artist (MAX(str(?album1)) as ?maxedAlbum) (count(distinct ?album2) as ?maxedCount) (count(?album2) as ?inferredCrossJoinCount)
WHERE {
?artist rdf:type dbpedia-owl:Artist .
?album1 ?p ?artist .
?album2 ?p ?artist .
FILTER (sameTerm(?p, prop:artist))
FILTER (str(?album1) < str(?album2))
}
GROUP BY ?artist
#HAVING count(?album2)<= 50
LIMIT 5
}
?outputAlbum ?p ?artist .
FILTER (sameTerm(?p, prop:artist))
FILTER (str(?outputAlbum) < str(?maxedAlbum))
}
Max and I had a bit of discussion in a chat,这可能最终会成为 Max 采取的相同方法。不过,我认为它更具可读性。它有 15 位艺术家的专辑,每人最多 5 张专辑。如果您希望能够包括没有任何专辑的艺术家,您需要将某些部分设为可选。
select ?artist ?album {
#-- select 15 bands that have albums (i.e.,
#-- such that they are the artist *of* something).
{
select distinct ?artist {
?artist a dbpedia-owl:Band ;
^dbpedia-owl:artist []
}
limit 15
}
#-- grab ordered pairs (x,y) (where y > x) of their
#-- albums. By asking how many x's for each y, we
#-- get just the first n y's.
?artist ^dbpedia-owl:artist ?album, ?album_
filter ( ?album_ <= ?album )
}
group by ?artist ?album
having count(?album_) <= 5 #-- take up 5 albums for each artist
order by ?artist ?album
以下 freebase MQL 找到 5 位艺术家和每位艺术家的 50 张专辑。
[{
"type" : "/music/artist",
"name":null,
"album" : [{
"name" : null,
"count":null,
"limit":50
}],
"limit":5
}]
第一次尝试 - 没有子查询
我可以这样写 SPARQL:
SELECT ?artist ?album
WHERE
{
?artist :type :/music/artist .
?artist :album ?album
}
LIMIT n
但是,我不知道应该指定多少 n
,因为据我所知,SPARQL 没有层次结构。
第二次尝试 - 使用子查询(不确定是否正常工作)
以下子查询看起来有效。
SELECT ?artist ?album
WHERE
{
?artist :album ?album .
{
SELECT ?artist
WHERE
{
?artist :type :/music/artist
}
LIMIT k
}
}
LIMIT n
但我不知道如何指定k
、n
来为每5位艺术家获得50张专辑。
一些具有端点的数据
- SPARQL 端点:http://dbpedia.org/sparql
谁能写出 SPARQL
打印 5 位艺术家和他们的 5 幅画作?
下面的查询打印了艺术家和他们的绘画,但没有 LIMIT
结果。
PREFIX dbpedia-owl:<http://dbpedia.org/ontology/>
PREFIX prop:<http://dbpedia.org/property/>
SELECT ?painting ?artist
WHERE
{
?painting prop:artist ?artist .
{
SELECT ?artist
{
?artist rdf:type dbpedia-owl:Artist.
}
}
}
谢谢。
根据你想要得到的结果,这涉及某种嵌套的相关子查询处理,这在单个 SPARQL 查询中是不直接可行的(至少在我的理解中,但如果可能的话,我完全在 ;) ):
Due to the bottom-up nature of SPARQL query evaluation, the subqueries are evaluated logically first, and the results are projected up to the outer query.
在与子查询的连接评估之后应用的第二个限制子句,它只会限制外部查询的结果数。
在第二次尝试的子查询中使用 LIMIT k (k=5) 子句将有效地 return 您需要的 5 位艺术家,但将 n 限制为 50 只会强制专辑结果(外部查询)所有这 5 位艺术家的全球 50 个结果,而不是您想要的 50 个/艺术家。将查询由内而外翻转会给您类似的效果。
编辑:
一个可能的解决方案是为所有 artists/albums 构建一个子查询,并将子查询限制在(以某种方式)订购的专辑数量低于 50 的地方(这里使用专辑 title IRI 排序)
PREFIX dbpedia-owl:<http://dbpedia.org/ontology/>
PREFIX prop:<http://dbpedia.org/property/>
SELECT ?artist ?outputAlbum
WHERE
{
{
SELECT ?artist (MAX(str(?album1)) as ?maxedAlbum)
WHERE {
?album1 prop:artist ?artist .
?album2 prop:artist ?artist .
FILTER (str(?album2) < str(?album1))
}
GROUP BY ?artist
HAVING count(?album2)<= 50
LIMIT 5
}
?outputAlbum prop:artist ?artist .
FILTER (str(?outputAlbum) < str(?maxedAlbum))
}
编辑 2:最后一个查询将是天真的方法,但似乎在 dbpedia 端点(如下所示)上有一些推论(未知的 re"gime)。更多精确查询将需要更多的过滤器和不同的子句——我在输出中添加了不同的和全局的计数以显示某处仍有一些推论):
PREFIX dbpedia-owl:<http://dbpedia.org/ontology/>
PREFIX prop:<http://dbpedia.org/property/>
SELECT ?artist ?outputAlbum ?maxedCount ?inferredCrossJoinCount
WHERE
{
{
SELECT ?artist (MAX(str(?album1)) as ?maxedAlbum) (count(distinct ?album2) as ?maxedCount) (count(?album2) as ?inferredCrossJoinCount)
WHERE {
?artist rdf:type dbpedia-owl:Artist .
?album1 ?p ?artist .
?album2 ?p ?artist .
FILTER (sameTerm(?p, prop:artist))
FILTER (str(?album1) < str(?album2))
}
GROUP BY ?artist
#HAVING count(?album2)<= 50
LIMIT 5
}
?outputAlbum ?p ?artist .
FILTER (sameTerm(?p, prop:artist))
FILTER (str(?outputAlbum) < str(?maxedAlbum))
}
Max and I had a bit of discussion in a chat,这可能最终会成为 Max 采取的相同方法。不过,我认为它更具可读性。它有 15 位艺术家的专辑,每人最多 5 张专辑。如果您希望能够包括没有任何专辑的艺术家,您需要将某些部分设为可选。
select ?artist ?album {
#-- select 15 bands that have albums (i.e.,
#-- such that they are the artist *of* something).
{
select distinct ?artist {
?artist a dbpedia-owl:Band ;
^dbpedia-owl:artist []
}
limit 15
}
#-- grab ordered pairs (x,y) (where y > x) of their
#-- albums. By asking how many x's for each y, we
#-- get just the first n y's.
?artist ^dbpedia-owl:artist ?album, ?album_
filter ( ?album_ <= ?album )
}
group by ?artist ?album
having count(?album_) <= 5 #-- take up 5 albums for each artist
order by ?artist ?album