问题描述
这是另一个 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_A
和 Package_B
,而 Package_C
和 Package_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_D
和 Platform_1
({{1} } 不在指定列表中)。 Platform_2
、Platform_2
和 Package_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))
}
}