我想写一个查询,通过使用图的其他一些属性过滤掉一些结果。我用这个例子来解释。
我正在模拟一个权限系统。有一些主题、资源和权限。主题对资源有一定的权限。某些权限意味着其他权限。这是一个简单的例子,有3个权限和3个资源,单个主题拥有其中一个(一种情况下两个)权限。
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX : <http://schema#>
PREFIX d: <http://data#>
INSERT DATA {
:Permission rdf:type rdf:Property .
:Read rdf:type rdf:Property ;
rdfs:subPropertyOf :Permission .
:Write rdf:type rdf:Property ;
rdfs:subPropertyOf :Permission ;
:implies :Read .
:Admin rdf:type rdf:Property ;
rdfs:subPropertyOf :Permission ;
:implies :Write ,
:Read .
d:s1 rdf:type :Subject .
d:r1 rdf:type :Resource .
d:r2 rdf:type :Resource .
d:r3 rdf:type :Resource .
d:s1 :Admin d:r1 .
d:s1 :Read d:r1 .
d:s1 :Write d:r2 .
d:s1 :Read d:r3 .
}
我可以很容易地编写一个查询,查看给定主题在某些资源上的隐含权限。
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX : <http://schema#>
PREFIX d: <http://data#>
SELECT DISTINCT ?subject ?resource ?implied (?permission AS ?implied_by)
WHERE {
BIND(d:s1 AS ?subject)
?resource rdf:type :Resource .
?subject rdf:type :Subject .
?permission rdfs:subPropertyOf :Permission ;
:implies* ?implied .
?subject ?permission ?resource .
}
这将产生如下结果:
+----------------+----------------+---------------------+---------------------+
| subject | resource | implied | implied_by |
+----------------+----------------+---------------------+---------------------+
| http://data#s1 | http://data#r1 | http://schema#Admin | http://schema#Admin |
| http://data#s1 | http://data#r1 | http://schema#Read | http://schema#Admin |
| http://data#s1 | http://data#r1 | http://schema#Write | http://schema#Admin |
| http://data#s1 | http://data#r1 | http://schema#Read | http://schema#Read |
| http://data#s1 | http://data#r3 | http://schema#Read | http://schema#Read |
| http://data#s1 | http://data#r2 | http://schema#Write | http://schema#Write |
| http://data#s1 | http://data#r2 | http://schema#Read | http://schema#Write |
+----------------+----------------+---------------------+---------------------+
我想做的是编写一个查询,只返回每个资源的最小权限列表,这意味着所有其他资源。任何关于我如何有效实现这一目标的想法都是非常受欢迎的。
这看起来有点像
MAX
聚合,但实际上需要一个图来确定结果。例如,理想的结果是:
+----------------+----------------+---------------------+---------------------+
| subject | resource | implied | implied_by |
+----------------+----------------+---------------------+---------------------+
| http://data#s1 | http://data#r1 | http://schema#Admin | http://schema#Admin |
| http://data#s1 | http://data#r3 | http://schema#Read | http://schema#Read |
| http://data#s1 | http://data#r2 | http://schema#Write | http://schema#Write |
+----------------+----------------+---------------------+---------------------+
请注意,数据和查询实际上比这更复杂,因此我绝对有必要使用参数路径,尽管我想去掉它引入的大部分信息。
?permission rdfs:subPropertyOf :Permission ;
:implies* ?implied .
还要注意的是,我想给每个权限添加一个整数值,这样我就可以简单地得到这个字段的最小值,但我的权限结构在现实中不是单一根的,所以有时候这并不合适。
实际上,问题是如何删除其他结果(针对该资源)隐含的任何权限(针对该资源)