SPARQL查询,从RDF数据中选择/构造最新版本

SPARQL查询,从RDF数据中选择/构造最新版本,rdf,sparql,Rdf,Sparql,我有一个RDF文件,用于跟踪项目修订。使用这些数据,我可以追溯在项目生命周期内对项目所做的更改。一旦特定版本发生更改,相应的数据将作为新版本放置。看一看 @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . @prefix mymeta: <http://www.mymeta.com/me

我有一个RDF文件,用于跟踪项目修订。使用这些数据,我可以追溯在项目生命周期内对项目所做的更改。一旦特定版本发生更改,相应的数据将作为新版本放置。看一看

@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix mymeta: <http://www.mymeta.com/meta/> .
@prefix dc: <http://purl.org/dc/elements/1.1/> .

<urn:ITEMID:12345> rdf:type mymeta:item .
<urn:ITEMID:12345> mymeta:itemchange <urn:ITEMID:12345:REV-1> .
<urn:ITEMID:12345:REV-1> dc:title "Product original name"@en .
<urn:ITEMID:12345:REV-1> dc:issued "2006-12-01"@en .
<urn:ITEMID:12345:REV-1> dc:format "4 x 6 x 1 in"@en .
<urn:ITEMID:12345:REV-1> dc:extent "200"@en .

<urn:ITEMID:12345> rdf:type mymeta:item .
<urn:ITEMID:12345> mymeta:itemchange <urn:ITEMID:12345:REV-2> .
<urn:ITEMID:12345:REV-2> dc:title "Improved Product Name"@en .
<urn:ITEMID:12345:REV-2> dc:issued "2007-06-01"@en .
@前缀rdf:。
@前缀rdfs:。
@前缀mymeta:。
@前缀dc:。
rdf:键入mymeta:item。
mymeta:itemchange。
dc:标题“产品原始名称”@en。
dc:已发出“2006-12-01”@en。
dc:格式为“@en”中的“4x6x1”。
直流:范围“200”@en。
rdf:键入mymeta:item。
mymeta:itemchange。
dc:title“改进产品名称”@en。
dc:发布“2007-06-01”@en。
根据该数据,在“2007-06-01”上有一个项目修订,其中只有项目名称更改为“改进产品名称”。如您所见,最新数据修订版中缺少“dc:format”和“dc:extent”。这是为了避免数以百万计的重复记录

我可以编写一个SPARQL查询,向我显示最新的产品版本信息(REV-2:dc:title和dc:issued),但它缺少“dc:format”和“dc:extent”,我希望从上一个版本(REV-1)中继承它


如何编写SPARQL查询来实现这一点?非常感谢任何帮助

不确定您可以在一个查询中完成此操作。如果可以的话,我会考虑更多,但以下两个问题可能会让您朝着正确的方向开始:

1) 查找没有格式的更改

PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX mymeta: <http://www.mymeta.com/meta/>
PREFIX dc: <http://purl.org/dc/elements/1.1/>

DESCRIBE ?change
WHERE 
{
    ?item a mymeta:item;
             mymeta:itemchange ?change.
    ?change ?p ?o.
    OPTIONAL 
    {
        ?change dc:format ?format .
    }
    FILTER (!bound(?format)) 
}
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX mymeta: <http://www.mymeta.com/meta/>
PREFIX dc: <http://purl.org/dc/elements/1.1/>

SELECT DISTINCT ?format
WHERE {
    ?item a mymeta:item;
             mymeta:itemchange ?change.
    ?change  dc:format ?format;
                  dc:issued ?issued.
    OPTIONAL {
        ?moreRecentItem a mymeta:item;
                ?moreRecentItem dc:issued ?moreRecentIssued.
        FILTER (?moreRecentIssued > ?issued)}
    FILTER (?bound (?moreRecentIssued))
}
前缀rdf:
前缀rdfs:
前缀mymeta:
前缀dc:
描述?改变
哪里
{
?项目a mymeta:项目;
mymeta:itemchange?更改。
?更改?采购订单。
可选的
{
?更改dc:格式?格式。
}
过滤器(!绑定(?格式))
}
2) 我认为这将发现最古老的变化,确实有一个格式

PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX mymeta: <http://www.mymeta.com/meta/>
PREFIX dc: <http://purl.org/dc/elements/1.1/>

DESCRIBE ?change
WHERE 
{
    ?item a mymeta:item;
             mymeta:itemchange ?change.
    ?change ?p ?o.
    OPTIONAL 
    {
        ?change dc:format ?format .
    }
    FILTER (!bound(?format)) 
}
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX mymeta: <http://www.mymeta.com/meta/>
PREFIX dc: <http://purl.org/dc/elements/1.1/>

SELECT DISTINCT ?format
WHERE {
    ?item a mymeta:item;
             mymeta:itemchange ?change.
    ?change  dc:format ?format;
                  dc:issued ?issued.
    OPTIONAL {
        ?moreRecentItem a mymeta:item;
                ?moreRecentItem dc:issued ?moreRecentIssued.
        FILTER (?moreRecentIssued > ?issued)}
    FILTER (?bound (?moreRecentIssued))
}
前缀rdf:
前缀rdfs:
前缀mymeta:
前缀dc:
选择不同的格式
在哪里{
?项目a mymeta:项目;
mymeta:itemchange?更改。
?更改dc:格式?格式;
dc:发出?发出。
可选的{
?更多最近项目a mymeta:项目;
?最新dc:已发行?最新发行。
过滤器(?更多发行>?发行)}
过滤器(?绑定(?更多已发行))
}

通过更多的工作,可以将(2)的?格式限制为(1)结果的发布数据之前的发布日期变更。因此,对于(1)中的每一行,您将执行(2)以查找要使用的格式值。不过,如果使用基于规则的推理引擎而不是SPARQL,可能会获得更好的结果。我建议使用EulerSharp或Pellet。

我使用RDF四边形实现了这一点,将每个修订存储在一个单独的命名图中,并使用一个众所周知的命名图跟踪每个项目的最新修订以及所有修订

你的补丁算法的理论目前是有缺陷的,因为你没有识别最新版本的方法,并且你不能很容易地追溯到这些版本,以便找到最后一次出现三元组。此外,如果在最近的修订版中找不到三元组,您总是试图返回到以前的修订版以获取三元组,那么如何知道三元组是否在修订版中被合法删除


RDF数据库应该能够通过只存储一次文本和URI并使用指针构造三元组或四元组来限制复制量。您可能能够使它在简单的情况下工作,在这种情况下,您保存的每个修订都存储了所有内容。

对于单个项目,这是一个使用SPARQL 1.1的子查询的非常简单的查询。诀窍是按日期对具有给定属性的修订进行排序,并从最新修订中获取值。
values
表单仅用于指定要选择的项目。如果需要查询更多项目,可以将它们添加到
values
块中

前缀mymeta:
前缀dc:
选择?项目?标题?格式?范围{
值?项{}
#--通过检查指定标题的所有修订获取标题,
#--按日期订购,并采用最新的。方法相同
#--用于格式和范围。
{选择?标题{项目mymeta:itemchange[dc:title?标题;dc:issued?日期]。}
按描述(?日期)限制1}排序
{选择格式{项目mymeta:itemchange[dc:format?format;dc:issued?date]。}
按描述(?日期)限制1}排序
{选择范围{项目mymeta:itemchange[dc:extent?范围;dc:issued?日期]。}
按描述(?日期)限制1}排序
}
$sparql--data.n3--query.rq
----------------------------------------------------------------------------------
|项目|标题|格式|范围|
==================================================================================
|| |“改进产品名称”@en |“4 x 6 x 1 in”@en |“200”@en|
----------------------------------------------------------------------------------
如果确实需要对所有项目执行此操作,则可以使用另一个子查询来选择项目。也就是说,不要使用
值?项{…}
,而是使用:

{select?item{?item a mymeta:item}
虽然在最初的问题中没有提到,但是,如果您对获取所有属性的最新属性值感兴趣,您可以使用如下所示的子查询,它基于

选择项目属性值{
值?项{}
?项目mymeta:itemchange[?属性?值;dc:发布?日期]
#--此子查询查找中每个属性的最早日期
#--然后,在子查询之外,我们
#--检索与该日期关联的特定值。
{
选择?属性(最大(?日期)作为?日期){
?项目mymeta:itemchange[?属性[];dc:发行?日期]
}
按项目属性分组
}
}
------------