设置SPARQL的差异

Par*_*mar 2 sparql

在一些FILTER我最终得到2套之后,让我们说A1和A2,我想SELECT只在A1中那些没有出现在A2中的元素.我试图使用MINUS但没有成功.

当我们有类似的东西:

MINUS { ?s foaf:givenName "Bob" }
Run Code Online (Sandbox Code Playgroud)

我们需要事先知道我们想要减去什么.在我的情况下,我不知道任何属性如`foaf:givenName1,除了它们属于集合A2.(这是一个财产思想).

我很迷惑.有任何想法吗?

使用CLARITY示例编辑:

SELECT DISTINCT ?x ?y WHERE { 

?x swrc:listAuthor ?y.
?x swrc:author ?w.
FILTER (!regex(?y, " and ")).
?a swrc:listAuthor ?b.
?a swrc:author ?c.
FILTER regex(?b, " and ").
FILTER(?c != ?w).}
Run Code Online (Sandbox Code Playgroud)

所以我想对此做的是以下内容.使用listAuthor,我可以在"John Doe和John Nipper"这样的字符串中获取作者.利用这种格式,我希望让作者单独写一篇论文(在他们的作者列表中没有"和").前3行足够了.但也有一些作者撰写了2篇论文,其中1篇是论文,1篇是共同作者.我尝试以某种方式从第一个中减去它们.有任何想法吗?

Jos*_*lor 5

寻找没有合作者的作者

如果我正确地理解了你的问题,那么你就是在试图要求那些从未与其他人共同撰写论文的作者(和他们的论文).如果论文与作者有关​​,那么您实际上并不需要匹配作者列表来执行此操作:author.如果我们有一些数据可以使用,这些问题总是容易得多,所以请考虑以下数据:

@prefix : <http://stackoverflow.com/q/21391444/1281433/> .

:p1 :author :a, :b .
:p2 :author :a .
:p3 :author :b, :c .
:p4 :author :d .
Run Code Online (Sandbox Code Playgroud)

A用B写了一篇论文,也单独写了一篇.B已经用A写了一篇论文,并且还用C.写了一篇论文B.D写了一篇论文.

我们可以使用这样的查询来查找从未合着论文的所有作者(在本例中为D):

prefix : <http://stackoverflow.com/q/21391444/1281433/>

select ?author ?paper where {
  ?paper :author ?author .
  filter not exists { 
    ?paper2 :author ?author, ?otherAuthor .
    filter ( ?author != ?otherAuthor )
  }
}
Run Code Online (Sandbox Code Playgroud)

这对应于英语:

与作者一起查找论文,使得该作者没有与另一位作者的论文.

我们得到了预期的结果:

------------------
| author | paper |
==================
| :d     | :p4   |
------------------
Run Code Online (Sandbox Code Playgroud)

如果您仍想根据作者列表字符串中的正则表达式进行选择和排除,则可以使用

prefix : <http://stackoverflow.com/q/21391444/1281433/>

select ?author ?paper where {
  # find authors of papers with no coauthors
  ?paper :author ?author ; :listAuthor ?list .
  filter(!regex(?list," and "))

  # and remove those that coauthored some paper
  filter not exists { 
    ?paper2 :author ?author ; :listAuthor ?list2 .
    filter(regex(?list2," and "))
  }
}
Run Code Online (Sandbox Code Playgroud)

调试原始查询

原始查询可以缩写为以下,除了一些语法糖之外,它们完全相同.

SELECT DISTINCT ?x ?y WHERE { 
  ?x swrc:listAuthor ?y ; swrc:author ?w.
  FILTER (!regex(?y, " and ")).

  ?a swrc:listAuthor ?b ; swrc:author ?c.
  FILTER regex(?b, " and ").

  FILTER(?c != ?w).
}
Run Code Online (Sandbox Code Playgroud)

除开filter在端部,上的图案?x,?y并且?w从图案上完全独立的?a,?b?c.从第一个模式开始,每个论文的每个作者只需要一个作者就可以获得一个绑定(这意味着每个论文只有一个作者就有一个绑定).从第二种模式中,您将为每篇论文的每位作者与多位作者进行一次绑定.然后你基本上采用这两组(作者,纸)对的笛卡尔积,得到形式的结合(paper1,author1,paper2,author2),然后最后filter说"删除任何绑定,其中author1是与author2相同.

考虑一下这对我上面给出的数据意味着什么,但让我们看看论文:p1:p2.由于:a创作的:p1孤独,我们将不得不:a?w:p1?x:

?x   ?w
-------
:p1  :a
Run Code Online (Sandbox Code Playgroud)

然而,由于:a还撰写论文:p2:b,我们将有一些行?a?c:

?a   ?c
-------
:p2  :a
:p2  :b
Run Code Online (Sandbox Code Playgroud)

现在笛卡儿产品是:

?x  ?w  ?a  ?c
--------------
:p1 :a  :p2 :a
:p1 :a  :p2 :b
Run Code Online (Sandbox Code Playgroud)

过滤器删除了第一行,留下了我们

?x  ?w  ?a  ?c
--------------
:p1 :a  :p2 :b
Run Code Online (Sandbox Code Playgroud)

这有:a作为?w,即使:a合着论文与别人.一般来说:

  • 每篇?x都是一篇论文,有一位作者(?w).
  • 每个人?w都是单独撰写论文的作者(?x).
  • 每个?a是纸有多个作者,其中之一是?c,和其中一个(?w)(写了一篇论文?x)独自一人.
  • 每个人?c都是某人共同撰写论文(?a)的作者,该人曾独自撰写论文().?w?x