代码之家  ›  专栏  ›  技术社区  ›  dpwrussell

SPARQL按子图过滤/聚合结果

  •  1
  • dpwrussell  · 技术社区  · 8 年前

    我想写一个查询,通过使用图的其他一些属性过滤掉一些结果。我用这个例子来解释。

    我正在模拟一个权限系统。有一些主题、资源和权限。主题对资源有一定的权限。某些权限意味着其他权限。这是一个简单的例子,有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 .
    

    还要注意的是,我想给每个权限添加一个整数值,这样我就可以简单地得到这个字段的最小值,但我的权限结构在现实中不是单一根的,所以有时候这并不合适。

    实际上,问题是如何删除其他结果(针对该资源)隐含的任何权限(针对该资源)

    0 回复  |  直到 8 年前