通过在 MarkLogic8 中引入新的 BiTemporal 功能,您可以跟踪两个时间轴的变化:有效时间和系统时间。三元组也支持这些功能。所以你可以沿着这两个轴回到过去,并可能看到变化。但是,由于三元组存储在文档中并且双时态元数据存储在文档级别而不是三元组级别,因此您无法删除或更新特定的三元组。此外,您不能将新的 SPARQL 更新功能与时间三元组一起使用。下面是一个例子:

在第 1 天,我们添加以下三元组,我们假设它们始终为真:

<temporalTriples>
  <systemStart />
  <systemEnd />
  <validStart>2001-01-01T00:00:00Z</validStart>
  <validEnd>2999-01-01T00:00:00Z</validEnd>
  <sem:triples>
    <sem:triple>
      <sem:subject>Denver</sem:subject>
      <sem:predicate>state</sem:predicate>
      <sem:object>CO</sem:object>
    </sem:triple>
    <sem:triple>
      <sem:subject>San Francisco</sem:subject>
      <sem:predicate>state</sem:predicate>
      <sem:object>CA</sem:object>
    </sem:triple>
  </sem:triples>
</temporalTriples>

在第 2 天,我们添加以下三元组,因为我们认为 Luna 住在丹佛:
<temporalTriples>
  <systemStart />
  <systemEnd />
  <validStart>{current-dateTime()}</validStart>
  <validEnd>2999-01-01T00:00:00Z</validEnd>
  <sem:triples xmlns:sem="http://marklogic.com/semantics">
    <sem:triple>
      <sem:subject>Luna</sem:subject>
      <sem:predicate>city</sem:predicate>
      <sem:object>Denver</sem:object>
    </sem:triple>
  </sem:triples>
</temporalTriples>

现在在第 3 天,我们要将 Luna 市更改为 San Francisco,因此我们别无选择,只能添加另一个三元组:
<temporalTriples>
  <systemStart />
  <systemEnd />
  <validStart>{current-dateTime()}</validStart>
  <validEnd>2999-01-01T00:00:00Z</validEnd>
  <sem:triples xmlns:sem="http://marklogic.com/semantics">
    <sem:triple>
      <sem:subject>Luna</sem:subject>
      <sem:predicate>city</sem:predicate>
      <sem:object>San Francisco</sem:object>
    </sem:triple>
  </sem:triples>
</temporalTriples>

没有三重更新/删除的概念,有几个问题使 MarkLogic 无法正确回答某些问题:
  • 如果您要求所有有效的三元组(沿有效时间轴),您将获得包括 <Luna> <city> <Denver> 在内的所有三元组。
  • 如果您要求所有当前三元组(沿系统时间轴),您将再次获得所有三元组。
  • 如果您要求最新的三元组(沿两个轴),您只会得到 <Luna> <city> <San Francisco>

  • 这是一个提供所有有效三元组的示例查询:
    sem:sparql('SELECT *
      WHERE {
        ?s ?p ?o .
      }',
        (),
        (),
        sem:store(
          (),
          cts:and-query((
            cts:period-range-query(
              "valid",
              "ALN_CONTAINS",
              cts:period( xs:dateTime("2998-12-31T23:59:59Z") )
             ),
             cts:collection-query("temporalCollection"),
             cts:collection-query("temp/triples.xml")
         ))
       )
    )
    

    基于这些,您无法正确回答以下问题:
  • 如果您询问 Luna 现在居住的有效城市和州,您将得到丹佛和旧金山及其州。
  • 如果您询问 Luna 居住的最新城市和州,您将一无所获,因为定义城市和州之间联系的三元组不在最新的集合中。

  • 现将主要问题总结如下:
  • 将新的三元组添加到数据库中:ML8 双时态特征完美支持它。您可以及时返回并查看添加前的数据库。
  • 删除三元组:不支持。您只能使用 temporal:document-delete 从“最新”集合中删除最新插入的三元组。数据就在那里,你可以查询它。您也可能最终删除要保留的三元组,因为一组三元组存储在单个文档中。
  • 更新三元组(例如 Luna 从丹佛搬到旧金山)。理想情况下,您应该能够删除旧的三元组并插入新的三元组(类似于 ML8 SPARQL 更新功能),但由于不支持删除,您最终会将新旧三元组存储在数据库中/从数据库中返回.

  • 是否有删除/更新时间三元组的解决方法,以便我们可以回答示例问题?

    最佳答案

    我认为依靠系统轴而不是有效轴是有意义的。不同之处在于系统轴有助于识别数据何时进入系统以及何时到期(例如删除的时间等价物)。有效轴说明数据的语义有效性。它告诉它何时变得相关,以及何时失去/失去相关性。其次,系统轴由 MarkLogic 管理,因此它确保时间版本没有重叠的结束时间,我认为这是导致上述示例中的主要问题的原因。

    我不确定所描述的案例是否真的需要 BI-temporal。 MarkLogic 9 提供了使用 uni-temporal 的选项,例如仅使用系统轴。这将使维护更容易,因为您可以省略有效的轴属性,并且更可靠,因为您只需要在(临时)插入时关心系统启动时间。以前的版本会自动过期,因为 MarkLogic 会相应地更新以前版本的系统结束时间。

    我还认为,如果您按主题 iri 将三元组分组,并为每个主题 iri 创建一个文档,并进行临时管理,那将是最简单的。如果您更新特定主题的三元组,则可以进行时间节点更新以进行适当的三元组更改。如果您首先为住在丹佛的 Luna 插入一个三元组,然后(暂时)更新 Luna 三元组文档以说明 Luna 住在 SF,则旧版本会在最新版本的系统开始时间之前获得一个新的系统结束时间。

    然后,您可以运行受限于 cts:collection-query('latest') 的 SPARQL 查询以仅获取最新的时间三元组,运行 cts:lsqt-query(..) 以获取 LSQT 之前特定时间的三元组,或者使用系统开始和结束时间属性上的日期范围查询手动执行某些操作。

    哼!

    关于marklogic - 在 MarkLogic 8 中删除/更新双时态三元组,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33661662/

    10-13 01:14