这是重现问题所需的最少数据
@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 .
Run Code Online (Sandbox Code Playgroud)
这是我的查询
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}
}
Run Code Online (Sandbox Code Playgroud)
这是结果:
如您所见,其中三件物品具有价值artist1,另外三件物品具有价值artist2
有什么办法可以让我将每个结果限制为 2 个
首先是一些最少的数据,包括三位艺术家,以及每位艺术家的一些项目。我总是强调 Stack Overflow 上的最小数据这一点,因为这对于隔离问题很重要。在这种情况下,您仍然提供了一个相对较大的查询和我们需要的更多数据。由于我们知道问题在于如何对与多个项目相关的艺术家进行分组,因此这里需要的所有数据是与多个项目相关的一些艺术家。然后我们就可以轻松地检索它们,并轻松地将它们分组。
@prefix : <urn:ex:> .
:artist1 :p :a1, :a2, :a3, :a4 .
:artist2 :p :b2, :b2, :b3, :b4, :b5 .
:artist3 :p :c2 .
Run Code Online (Sandbox Code Playgroud)
现在,您可以选择艺术家及其项目,并且可以确定每个项目的索引。此方法检查每个项目有多少个其他项目小于等于它(总是至少有一个等于它(本身),因此计数本质上是一个基于 1 的索引)。
@prefix : <urn:ex:> .
:artist1 :p :a1, :a2, :a3, :a4 .
:artist2 :p :b2, :b2, :b3, :b4, :b5 .
:artist3 :p :c2 .
Run Code Online (Sandbox Code Playgroud)
-------------------------
| 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 |
-------------------------
Run Code Online (Sandbox Code Playgroud)
现在您可以使用必须过滤的位置,以便每个艺术家最多获得两个:
prefix : <urn:ex:>
select ?artist ?item (count(?item_) as ?pos){
?artist :p ?item_, ?item .
filter (str(?item_) <= str(?item))
}
group by ?artist ?item
Run Code Online (Sandbox Code Playgroud)
-------------------
| artist | item |
===================
| :artist1 | :a1 |
| :artist1 | :a2 |
| :artist2 | :b2 |
| :artist2 | :b3 |
| :artist3 | :c2 |
-------------------
Run Code Online (Sandbox Code Playgroud)
在 SPARQL 中执行“n per every x”查询是一种挑战,而且目前还没有很好的解决方案。一些可能有帮助的相关阅读(也请务必检查对这些问题和答案的评论),包括:
| 归档时间: |
|
| 查看次数: |
1215 次 |
| 最近记录: |