5

我有一个用于跟踪项目修订的 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 .

根据这个数据,“2007-06-01”有一个项目修订,只有项目名称被更改为“改进的产品名称”。如您所见,最新数据修订版中缺少“dc:format”和“dc:extent”。这是为了避免数百万条重复记录!

我可以编写一个 SPARQL 查询,向我显示最新的产品修订信息(REV-2:dc:title 和 dc:issued),但它缺少我想从最后一个结转的“dc:format”和“dc:extent”修订版(REV-1)。

如何编写 SPARQL 查询来执行此操作?非常感谢任何帮助!

4

3 回答 3

2

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

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)) 
}

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/>

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))
}

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

于 2010-03-09T22:30:44.147 回答
2

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

prefix mymeta: <http://www.mymeta.com/meta/> 
prefix dc: <http://purl.org/dc/elements/1.1/> 

select ?item ?title ?format ?extent where {
  values ?item { <urn:ITEMID:12345> }

  #-- Get the title by examining all the revisions that specify a title, 
  #-- ordering them by date, and taking the latest one.  The same approach
  #-- is used for the format and extent.
  { select ?title { ?item mymeta:itemchange [ dc:title ?title ; dc:issued ?date ] . }
    order by desc(?date) limit 1 }

  { select ?format { ?item mymeta:itemchange [ dc:format ?format ; dc:issued ?date ] . }
    order by desc(?date) limit 1 }

  { select ?extent { ?item mymeta:itemchange [ dc:extent ?extent ; dc:issued ?date ] . }
    order by desc(?date) limit 1 }
}
$ sparql --data data.n3  --query query.rq
----------------------------------------------------------------------------------
| item               | title                      | format            | extent   |
==================================================================================
| <urn:ITEMID:12345> | "Improved Product Name"@en | "4 x 6 x 1 in"@en | "200"@en |
----------------------------------------------------------------------------------

如果您确实需要对所有项目执行此操作,则可以使用另一个子查询来选择项目。也就是说,代替values ?item { ... },使用:

{ select ?item { ?item a mymeta:item } }

虽然原始问题中没有提到它,但它出现在评论中,如果您有兴趣获取所有属性的最新属性值,您可以使用以下子查询,该子查询基于How to限制 SPARQL 解决方案组的大小?

select ?item ?property ?value {
  values ?item { <urn:ITEMID:12345> }

  ?item mymeta:itemchange [ ?property ?value ; dc:issued ?date ]

  #-- This subquery finds the earliest date for each property in
  #-- the graph for each item.  Then, outside the subquery, we 
  #-- retrieve the particular value associated with that date.  
  {
    select ?property (max(?date_) as ?date) {
      ?item mymeta:itemchange [ ?property [] ; dc:issued ?date_ ]
    }
    group by ?item ?property
  }
}
---------------------------------------------------------------
| item               | property  | value                      |
===============================================================
| <urn:ITEMID:12345> | dc:issued | "2007-06-01"@en            |
| <urn:ITEMID:12345> | dc:title  | "Improved Product Name"@en |
| <urn:ITEMID:12345> | dc:extent | "200"@en                   |
| <urn:ITEMID:12345> | dc:format | "4 x 6 x 1 in"@en          |
---------------------------------------------------------------
于 2013-10-14T18:01:14.327 回答
-1

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

您的补丁算法理论目前存在缺陷,因为您没有识别最新修订版的方法,并且您无法轻松追溯修订版以找到最后一次发生三重奏的时间。此外,如果在最近的修订中找不到三元组,如果您总是尝试返回以前的修订版来获取三元组,那么您如何知道该三元组是否在修订版中被合法删除?

RDF 数据库应该能够通过只存储一次文字和 URI 并使用指针来构造三元组或四元组来限制重复的数量。您可能能够使其在天真的情况下工作,即为您保留的每个修订版本存储所有内容。

于 2013-07-09T03:50:12.177 回答