如何在Python rdflib中运行IN和NOT IN SPARQL语句以去除两个图的交集

7 投票
2 回答
9430 浏览
提问于 2025-04-16 16:22

我正在尝试在Python的SPARQL实现中使用INNOT IN语句(如果我没理解错的话,这些是在SPARQL 1.1中引入的),但是似乎这个语法没有被识别。

我们来考虑两个集合(A和B)。我想输出集合A中的内容,同时去掉集合B中的内容。

SELECT ?title WHERE {
   some logic defining ?item and ?SetB
   FILTER (?item NOT IN ?SetB)
}

也许这个特定的功能是在SPARQL 1.1中添加的,而rdfextra不支持它。如果真是这样的话,我希望能找到一个解决办法(或者告诉我如何不使用NOT IN关键字来实现这个功能)。

2 个回答

4

没有具体情况很难回答,但听起来你想要的是 MINUS

SELECT ?title WHERE {
    ?item ... ITEM CRITERIA ...
    MINUS { ?item ... SET CRITERIA ... }
}

举个例子:

SELECT ?title WHERE {
    ?item ex:colour "red" .       # item is red
    MINUS { ?item ex:size "big" } # but not in set of big things
}

NOT IN 这个说法有点让人误解:据我所知,它是作用于一个列表表达式,而不是你可以自己定义的列表。

7

我尝试过类似的查询,也遇到了解析异常。我查看了rdflib的SPARQL解析器的代码,发现似乎没有处理INNOT IN的规则。所以我猜这个功能可能还没实现。

不过,我不太确定你是否正确使用了它。看看SPARQL 1.1规范NOT IN的定义……它定义了IN运算符是用来对一系列表达式进行操作的。因此,你应该这样写:

FILTER (?item NOT IN (?SetB))

我不太确定右边能否使用变量,因为规范中的所有例子都使用了具体的术语。 编辑:参见RobV的消息,右边可以使用变量。

一种使用单个查询的解决方法

一个可能对你有用的解决方案是使用OPTIONALbound(这两个在rdflib中都支持)。可以这样写……

SELECT ?title WHERE {
   some logic defining ?item
   OPTIONAL {
   some logic defining ?SetB
   }
   FILTER (bound(?SetB) && ?setB != ?item)
}

在不了解你查询的更多信息的情况下,我无法给出更好的建议。

一种使用两个查询的解决方法

用rdflib解决这个问题最简单的方法是使用过滤器和两个查询。第一个查询获取所有可能的?SetB值。在第二个查询中,你动态创建一个过滤器:

SELECT ?title WHERE {
   some logic defining ?item
   FILTER (?item != <setb_val1> && ?item != <setb_val2> &&
   ... && ?item != <setb_val2>)
}

撰写回答