【问题标题】:Find individuals in SPARQL based on other relations / Compare sets根据其他关系/比较集在 SPARQL 中查找个人
【发布时间】:2014-07-14 06:47:28
【问题描述】:

给定的对象 :A、:B 和 :C 具有分配的属性,而这些属性本身不是标量,而是具有键和值属性的对象。

@prefix x: <http://example.com/example#> 

x:A x:hasProp x:Prop1 .
x:Prop1 x:Key "1" .
x:Prop1 x:Value "AA" .
x:B x:hasProp x:Prop2 .
x:Prop2 x:Key "1" .
x:Prop2 x:Value "AA" .
x:C x:hasProp x:Prop3 .
x:C x:hasProp x:Prop4 .
x:Prop3 x:Key "1" .
x:Prop3 x:Value "AA" .
x:Prop4 x:Key "2" .
x:Prop4 x:Value "BB" .

我如何断言 :A 和 :B 具有相同的属性,而 :A 和 :C 没有? 我是 SPARQL 的新手,我不知道... 我试过类似的东西:

prefix x: <http://example.com/example#> 

select ?another ?k ?v
{x:A x:hasProp ?p .
?p ?k ?v .
?another x:hasProp ?p2 .   
?p2 ?k ?v .
}

但我认为这是一种错误的方式。它还返回 :C。

如何在 SPARQL 中轻松比较两个集合?


补充问题: 来自答案 1 的查询可以正常工作,但前提是 :A 直接使用。使用变量代替 :A 使 :C 也符合条件。为什么?

我的意思是: 插入一些条件来查找:A

prefix : <http://example.com/example#> 

INSERT DATA {:A rdfs:label "A"}

然后使用变量代替 :A

prefix : <http://example.com/example#> 

select ?other ?k ?v {
  #-- Find ?other such that :A and ?other have
  #-- some property in common,
  ?a rdfs:label "A"
  ?a     :hasProp [ :Key ?k ; :Value ?v ] .
  ?other :hasProp [ :Key ?k ; :Value ?v ] .

  #-- but remove any ?other such that:
  filter not exists { 
#-- (i) :A has a property that ?other doesn't; 
  {
    ?a :hasProp [ :Key ?kk ; :Value ?vv ] .
    filter not exists { ?other :hasProp [ :Key ?kk ; :Value ?vv ] .
     }
  }
  union
  #-- or (ii) ?other has a property that :A doesn't.
  {
    ?other :hasProp [ :Key ?kk ; :Value ?vv ] .
    filter not exists {
         ?a :hasProp [ :Key ?kk ; :Value ?vv ] .
   }
 }
}  
}

更新:

prefix : <http://example.com/example#> 

INSERT DATA {
:A rdfs:label "A" .
:A :hasProp :Prop1 .
:Prop1 :Key "1" .
:Prop1 :Value "AA" .

:B :hasProp :Prop2 .
:Prop2 :Key "1" .
:Prop2 :Value "AA" .

:C :hasProp :Prop3 .
:C :hasProp :Prop4 .
:Prop3 :Key "1" .
:Prop3 :Value "AA" .

:Prop4 :Key "2" .
:Prop4 :Value "BB" .
}

使用 :A 查询

prefix : <http://example.com/example#> 

select ?other ?k ?v {
   :A    :hasProp [ :Key ?k ; :Value ?v ] .
   ?other :hasProp [ :Key ?k ; :Value ?v ] .
   filter not exists { 
     { :A :hasProp [ :Key ?kk ; :Value ?vv ] .
       filter not exists { ?other :hasProp [ :Key ?kk ; :Value ?vv ] .
       }
     }
     union
     {
      ?other :hasProp [ :Key ?kk ; :Value ?vv ] .
      filter not exists { :A :hasProp [ :Key ?kk ; :Value ?vv ] .
      }
   }
  }
 }

答案:

 -------------------  
 |other|  k  | v  
 |A    | "1" | "AA"  
 |B    | "1" | "AA"  
 -------------------  

使用变量 ?a 查询:

 prefix : <http://example.com/example#> 

select ?other ?k ?v {
   ?a rdfs:label "A" .
   ?a    :hasProp [ :Key ?k ; :Value ?v ] .
   ?other :hasProp [ :Key ?k ; :Value ?v ] .
   filter not exists { 
     { ?a :hasProp [ :Key ?kk ; :Value ?vv ] .
       filter not exists { ?other :hasProp [ :Key ?kk ; :Value ?vv ] .
       }
     }
     union
     {
      ?other :hasProp [ :Key ?kk ; :Value ?vv ] .
      filter not exists { ?a :hasProp [ :Key ?kk ; :Value ?vv ] .
      }
    }
   }
 }

返回

其他kv
一个“1”“AA”
B“1”“AA”
C“1”“AA”

【问题讨论】:

  • 我正在尝试做的事情:找到所有类似于 :A 的对象,因为它们在键/值方面具有完全相同的一组属性。 :B 必须符合条件,而 :C 不是因为 :C 多具有一个属性(Key=2,Value = BB)。我知道我的查询也应该返回:C,这就是我根据要求要求“正确”的原因。
  • 是的,完全相同的键/值对
  • 好的,我刚刚更新了我的答案。
  • 您可能还会发现Set difference in SPARQL 很有用。

标签: sparql semantic-web owl


【解决方案1】:

为什么你的查询没有返回你想要的……

显示您实际获得的输出总是有帮助的,因为这样您就可以指出哪些部分是您不期望的。在这种情况下,您的查询返回:

---------------------------
| another | k      | v    |
===========================
| :C      | :Value | "AA" |
| :C      | :Key   | "1"  |
| :B      | :Value | "AA" |
| :B      | :Key   | "1"  |
| :A      | :Value | "AA" |
| :A      | :Key   | "1"  |
---------------------------

这在您的情况下是有道理的,因为 C 确实具有您要询问的那种数据。这是您的这部分数据:

x:A x:hasProp x:Prop1 .
x:Prop1 x:Key "1" .
x:Prop1 x:Value "AA" .
…
x:C x:hasProp x:Prop3 .
…
x:Prop3 x:Key "1" .
x:Prop3 x:Value "AA" .

返回所需内容的查询

下面是我编写查询的方法,可以得到你想要的。很容易找到与:A 有共同属性的东西。从这些中,您需要过滤掉任何?other,这样:A 具有?other 没有的属性,或者?other 具有:A 没有的属性,

prefix : <http://example.com/example#> 

select ?other ?k ?v {
  #-- Find ?other such that :A and ?other have
  #-- some property in common,
  :A     :hasProp [ :Key ?k ; :Value ?v ] .
  ?other :hasProp [ :Key ?k ; :Value ?v ] .

  #-- but remove any ?other such that:
  filter not exists { 
    #-- (i) :A has a property that ?other doesn't; 
    {
      :A :hasProp [ :Key ?kk ; :Value ?vv ] .
      filter not exists {
        ?other :hasProp [ :Key ?kk ; :Value ?vv ] .
      }
    }
    union
    #-- or (ii) ?other has a property that :A doesn't.
    {
      ?other :hasProp [ :Key ?kk ; :Value ?vv ] .
      filter not exists {
        :A :hasProp [ :Key ?kk ; :Value ?vv ] .
      }
    }
  }
}
----------------------
| other | k   | v    |
======================
| :B    | "1" | "AA" |
| :A    | "1" | "AA" |
----------------------

枚举等价类

事实上,您可以使用它的概括来列出数据中的不同等价类。

prefix : <http://example.com/example#> 

select distinct ?x ?y {
  ?x :hasProp [] .
  ?y :hasProp [] .

  filter not exists { 
    {
      ?x :hasProp [ :Key ?kk ; :Value ?vv ] .
      filter not exists {
        ?y :hasProp [ :Key ?kk ; :Value ?vv ] .
      }
    }
    union
    {
      ?y :hasProp [ :Key ?kk ; :Value ?vv ] .
      filter not exists {
        ?x :hasProp [ :Key ?kk ; :Value ?vv ] .
      }
    }
  }
}
order by ?x ?y
-----------
| x  | y  |
===========
| :A | :A |
| :A | :B |
| :B | :A |
| :B | :B |
| :C | :C |
-----------

【讨论】:

  • 它在这种形式下工作正常,但它不适用于我使用变量代替:A。为什么?
  • 我发布了 2 个不同的查询。当您说“那个表格”时,您指的是哪一个?
  • 我的意思是第一个查询。我已经扩展了我最初的问题以显示这一点。
  • 您确定您的插入工作正常吗?该查询(没有关于rdfs:label 的信息)在您的原始数据上工作得很好。如果您遇到不同情况的问题,我建议您尝试构建一个可以观察问题的最小工作示例。
  • 我更新了我的问题以显示数据和两个查询。第二个也返回:C.
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-25
  • 2017-03-24
  • 1970-01-01
相关资源
最近更新 更多