SPARQL:仅构造图中尚未存在的三元组

问题描述 投票:0回答:1

我想实现一个 SPARQL 构造查询,它仅构造图中尚未存在的三元组。

考虑以下示例图:

@prefix crm: <http://www.cidoc-crm.org/cidoc-crm/> .
@prefix sdhss: <https://r11.eu/ns/prosopography/> .
@prefix : <http://www.example.org/> .

:0b5000b1e9 a sdhss:C23 .

:cebbd8cac9 a :E13_sdhss_P36 ;
    crm:P140_assigned_attribute_to :0b5000b1e9 ;
    crm:P141_assigned [ a crm:E21_Person ] ;
    crm:P14_carried_out_by :d4f0bc5a29 ;
    crm:P17_was_motivated_by :41cf6794ba .

:b427419ad6 a :E13_sdhss_P35 ;
    crm:P140_assigned_attribute_to :0b5000b1e9 ;
    crm:P141_assigned [ a sdhss:C24 ] .


:b427419ad7 a :E13_sdhss_P4 ;
    crm:P140_assigned_attribute_to :0b5000b1e9 ;
    crm:P141_assigned [ a crm:P52_Time-Span] .

为了为 E13_sdhss_P35/P4 实例构造缺失的 P14/P17 三元组,我想出了这样的方法:

prefix : <http://www.example.org/> 
prefix crm: <http://www.cidoc-crm.org/cidoc-crm/> 
prefix sdhss: <https://r11.eu/ns/prosopography/> 

construct {
  ?e13_a2 crm:P14_carried_out_by ?agent ;
          crm:P17_was_motivated_by ?source .
  ?e13_a3 crm:P14_carried_out_by ?agent ;
          crm:P17_was_motivated_by ?source .
}
where {
  ?c23 a sdhss:C23 .

  ?e13_a1 a :E13_sdhss_P36 ;
       crm:P140_assigned_attribute_to ?c23 ;
       crm:P141_assigned [ a crm:E21_Person ] ;
       crm:P14_carried_out_by ?agent ;
       crm:P17_was_motivated_by ?source .

  ?e13_a2 a :E13_sdhss_P35 ;
       crm:P140_assigned_attribute_to ?c23 ;
       crm:P141_assigned [ a sdhss:C24 ] .
  
  ?e13_a3 a :E13_sdhss_P4 ;
       crm:P140_assigned_attribute_to ?c23 ;
       crm:P141_assigned [ a crm:P52_Time-Span ] .

  minus {
    {?e13_a2 crm:P14_carried_out_by ?agent .}
    union
    {?e13_a2 crm:P17_was_motivated_by ?source .}
    union
    {?e13_a3 crm:P14_carried_out_by ?agent .}
    union
    {?e13_a3 crm:P17_was_motivated_by ?source .}
  }
}

这个想法是根据 minus 子句中的模式过滤结果集,并且仅将剩余的绑定传递给构造子句。

这适用于给定的示例图,但是一旦我为

E13_sdhss_P35
E13_sdhss_P4
添加 P14/P17 断言,构造查询就会一起返回空。

例如对于使用 P14/P17 断言沿 `E13_sdhss_P35:

进行的以下修改,查询返回空
@prefix crm: <http://www.cidoc-crm.org/cidoc-crm/> .
@prefix sdhss: <https://r11.eu/ns/prosopography/> .
@prefix : <http://www.example.org/> .

:0b5000b1e9 a sdhss:C23 .

:cebbd8cac9 a :E13_sdhss_P36 ;
    crm:P140_assigned_attribute_to :0b5000b1e9 ;
    crm:P141_assigned [ a crm:E21_Person ] ;
    crm:P14_carried_out_by :d4f0bc5a29 ;
    crm:P17_was_motivated_by :41cf6794ba .

:b427419ad6 a :E13_sdhss_P35 ;
    crm:P140_assigned_attribute_to :0b5000b1e9 ;
    crm:P141_assigned [ a sdhss:C24 ] ;
    crm:P14_carried_out_by :d4f0bc5a29 ;
    crm:P17_was_motivated_by :41cf6794ba .


:b427419ad7 a :E13_sdhss_P4 ;
    crm:P140_assigned_attribute_to :0b5000b1e9 ;
    crm:P141_assigned [ a crm:P52_Time-Span] .

我正在本地 Fuseki 设置上对此进行测试,在实时 GraphDB 实例上,类似的查询似乎工作得很好。

sparql construct
1个回答
0
投票

可能的解决方案:

prefix crm: <http://www.cidoc-crm.org/cidoc-crm/> 
prefix sdhss: <https://r11.eu/ns/prosopography/> 
prefix : <http://www.example.org/> 


construct {
  ?e13_a2_p14 crm:P14_carried_out_by ?agent .
  ?e13_a2_p17 crm:P17_was_motivated_by ?source .
}
where {
  ?c23 a sdhss:C23 .
  ?e13_a1 a :E13_sdhss_P36 ;
          crm:P140_assigned_attribute_to ?c23 ;
          crm:P141_assigned [ a crm:E21_Person ] ;
          crm:P14_carried_out_by ?agent ;
          crm:P17_was_motivated_by ?source .

  {
    ?e13_a2_p14 a :E13_sdhss_P35 ;
                crm:P140_assigned_attribute_to ?c23 ;
                crm:P141_assigned [ a sdhss:C24 ] .
    filter not exists { ?e13_a2_p14 crm:P14_carried_out_by ?agent . }
  }
  union
  {
    ?e13_a2_p17 a :E13_sdhss_P35 ;
                crm:P140_assigned_attribute_to ?c23 ;
                crm:P141_assigned [ a sdhss:C24 ] .
    filter not exists { ?e13_a2_p17 crm:P17_was_motivated_by ?source . }
  }
}

早期尝试的问题显然是,一旦 minus/filter 子句匹配,SPARQL 处理器就会从结果集中删除绑定,并且构造子句的机制显然是这样的,只有在所有变量都绑定时才会生成三元组;因此,一旦单个减/过滤子句捕获到某些内容,?e13_a2 就会解除绑定,因此根本不会生成三元组。 这也解释了我之前所做的一个观察,即减号/过滤子句的顺序在之前的尝试中很重要,例如OP减/工会提案。

在应用过滤器约束之前,通过专门命名主题变量(?e13_a2_p14,?e13_a2_p17)可以解决在减号/过滤器匹配上丢失 e13_a2 绑定的问题。

© www.soinside.com 2019 - 2024. All rights reserved.