这是重现问题所需的最低数据
@prefix : <http://example.org/rs#>
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
:artist1 rdf:type :Artist .
:artist2 rdf:type :Artist .
:artist3 rdf:type :Artist .
:en rdf:type :Language .
:it rdf:type :Language .
:gr rdf:type :Language .
:c1
rdf:type :CountableClass ;
:appliedOnClass :Artist ;
:appliedOnProperty :hasArtist
.
:c2
rdf:type :CountableClass ;
:appliedOnClass :Language ;
:appliedOnProperty :hasLanguage
.
:i1
rdf:type :RecommendableClass ;
:hasArtist :artist1 ;
:hasLanguage :en
.
:i2
rdf:type :RecommendableClass ;
:hasArtist :artist1 ;
:hasLanguage :en
.
:i3
rdf:type :RecommendableClass;
:hasArtist :artist1 ;
:hasLanguage :it
.
:i4
rdf:type :RecommendableClass;
:hasArtist :artist2 ;
:hasLanguage :en
.
:i5
rdf:type :RecommendableClass;
:hasArtist :artist2 ;
:hasLanguage :it
.
:i6
rdf:type :RecommendableClass;
:hasArtist :artist3 ;
:hasLanguage :gr
.
:ania :likes :i1 .
:ania :likes :i3 .
:ania :likes :i4 .
这是我的查询
PREFIX : <http://example.org/rs#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rs: <http://spektrum.ctu.cz/ontologies/radio-spectrum#>
SELECT ?item ?count ?value
WHERE
{ ?item rdf:type :RecommendableClass
{ SELECT ?countableProperty ?value (count(*) AS ?count)
WHERE
{ VALUES ?user { :ania }
VALUES ?countableConfiguration { :c1 }
?user :likes ?x .
?countableConfiguration :appliedOnProperty ?countableProperty .
?countableConfiguration :appliedOnClass ?countableClass .
?x ?countableProperty ?value .
?value rdf:type ?countableClass
}
GROUP BY ?countableProperty ?value
ORDER BY DESC(?count)
LIMIT 3
}
FILTER NOT EXISTS {?user :likes ?item}
}
结果如下:
如您所见,有三个项目的值为artist1
,另外三个项目的值为artist2
有什么办法可以将结果限制为每个只有2个
答案 0 :(得分:2)
首先是一些最小的数据,有三位艺术家,每一位都有一些项目。我总是强调Stack Overflow上的最小数据,因为它对于隔离问题很重要。在这种情况下,您仍然提供了一个相对较大的查询和我们需要的更多数据。由于我们知道问题在于如何对每个与多个项目相关的艺术家进行分组,因此这里所需的所有数据都是一些与多个项目相关的艺术家。然后我们可以轻松地检索它们,并轻松地将它们分组。
@prefix : <urn:ex:> .
:artist1 :p :a1, :a2, :a3, :a4 .
:artist2 :p :b2, :b2, :b3, :b4, :b5 .
:artist3 :p :c2 .
现在,您可以选择艺术家及其项目,并可以确定每个项目的索引。此方法检查每个项目有多少其他项目小于等于它(总是至少有一个等于它(本身),因此计数基本上是从1开始的索引)
prefix : <urn:ex:>
select ?artist ?item (count(?item_) as ?pos){
?artist :p ?item_, ?item .
filter (str(?item_) <= str(?item))
}
group by ?artist ?item
-------------------------
| artist | item | pos |
=========================
| :artist1 | :a1 | 1 |
| :artist1 | :a2 | 2 |
| :artist1 | :a3 | 3 |
| :artist1 | :a4 | 4 |
| :artist2 | :b2 | 1 |
| :artist2 | :b3 | 2 |
| :artist2 | :b4 | 3 |
| :artist2 | :b5 | 4 |
| :artist3 | :c2 | 1 |
-------------------------
现在您可以使用 来过滤该位置,这样每个艺术家最多可以获得两个:
prefix : <urn:ex:>
select ?artist ?item {
?artist :p ?item_, ?item .
filter (str(?item_) <= str(?item))
}
group by ?artist ?item
having (count(?item_) < 3)
-------------------
| artist | item |
===================
| :artist1 | :a1 |
| :artist1 | :a2 |
| :artist2 | :b2 |
| :artist2 | :b3 |
| :artist3 | :c2 |
-------------------
在SPARQL中执行“每个x”n个查询是一种挑战,而且还没有很好的解决方案。一些可能有帮助的相关阅读(一定要检查对这些问题和答案的评论),包括: