递归地将过滤器应用于连接的顶点SPARQL

问题描述

这是另一个 question I posted 的后续问题,关于使用 RDF 的 SPAQRL 提出一个查询,该查询过滤掉所有与其他顶点有任何边的顶点,这些顶点不在指定值列表中,例如我收到了 a working answer

这是我正在使用的图形的可视化表示,其中包含两种独立 RDF 类型(:package:platform)的节点。在此图中,包(:Package_A:Package_B:Package_C:Package_D)具有到它们所需的每个平台的外向边,平台的值为 {{ 1}} 和 :Platform_1:

在此后续中,包现在也可以依赖于其他包,这在图上使用从 :Platform_2 到另一个 :requires:package 边表示,当它具有依赖它。

在上图中,:package 需要 Package_APackage_B,而 Package_CPackage_B 都需要 Package_C

这是创建此图的数据:

Package_D

我能够查询此图以过滤掉所有 INSERT DATA { :Package_A rdf:type :package . :Package_B rdf:type :package . :Package_C rdf:type :package . :Package_D rdf:type :package . :Platform_1 rdf:type :platform . :Platform_2 rdf:type :platform . :Package_A :platform :Platform_1 . :Package_B :platform :Platform_1 . :Package_C :platform :Platform_1 . :Package_D :platform :Platform_1 . :Package_D :platform :Platform_2 . :Package_A :requires :Package_B . :Package_A :requires :Package_C . :Package_B :requires :Package_D . :Package_C :requires :Package_D . } 顶点,这些顶点与不在指定值列表中的其他顶点有任何边。 例如,对于这个指定的单例列表::package,以下查询过滤掉 [:Platform_1],因为它包含 Package_DPlatform_1 ({{1} } 不在指定列表中)。 Platform_2Platform_2Package_A 被返回,因为这些包只有具有通向 Package_B 的边。

Package_C

我现在正在尝试扩展此查询,以便它还过滤掉 Platform_1 满足相同条件的任何其他包(直接或传递)的任何顶点,并且具有到一个值的传出边不在指定的列表中。

意味着在列表SELECT * { ?package a :package . FILTER NOT EXISTS { ?package :platform ?platform . FILTER (?platform NOT IN(:Platform_1)) } } 的情况下,所有包应该被过滤掉,因为所有包在:requires上至少有一个可传递的[:Platform_1],它有一个:requires 的 :platform 边缘,它不在指定的列表中。

在列表 Package_D 的情况下,应返回所有包顶点,因为所有包顶点只有连接到 Platform_2[:Platform_1,:Platform_2] 的边。

我尝试使用递归运算符 Platform_1 作为获取所有传递 Platform_2 路径的一种方式,并对其应用上述相同的过滤器。但是,这在指定列表 * 时不起作用,因为此查询的结果仍包含 :requires[:Platform_1]Package_A

Package_B

任何人都知道我如何构建一个查询,该查询过滤掉所有顶点到其他不在指定值列表中的顶点的任何边,并过滤掉任何具有 Package_C 边的顶点(直接或传递)导致另一个满足相同条件的顶点?

解决方法

一个非常发人深省的问题。 在您的查询中,您希望过滤掉任何依赖于其他包的包,这些包的平台位于已批准平台列表的“外部”。

以下查询将起作用:

SELECT * {
    ?package a :package .
     FILTER NOT EXISTS {
         ?package :requires* ?requirement .
         ?requirement :platform ?platform .
         FILTER (?platform NOT IN(:Platform_1))
     }
}

与您的查询不同的是,它是具有平台的要求,而不是包。 * 将处理没有要求(即包 D)的情况,以及当我们查看包本身的平台时。

为简洁起见,当您对需求列表不感兴趣时​​,您可以这样表达上述查询:

SELECT * {
        ?package a :package .
         FILTER NOT EXISTS {
             ?package :requires*/:platform ?platform . #Notice the /.
             FILTER (?platform NOT IN(:Platform_1))
         }
    }

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...