Удаление / Обновление BiTemporal Тройки в MarkLogic 8

С введением новых функций BiTemporal в MarkLogic8 вы можете отслеживать изменения по двум временным осям: действительное и системное время. Эти функции также поддерживаются для троек. Таким образом, вы можете вернуться во времени вдоль этих двух осей и, возможно, увидеть изменения. Однако, поскольку тройки хранятся в документах, а битемпоральные метаданные хранятся на уровне документов, а не на тройном уровне, вы не можете удалить или обновить конкретную тройку. Кроме того, вы не можете использовать новые функции обновления SPARQL с временными тройками. Вот пример:

В первый день мы добавляем следующие тройки, которые, как мы предполагаем, всегда верны:

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

Во второй день мы добавляем следующую тройку, поскольку мы думаем, что Луна живет в Денвере:

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

Теперь, в третий день, мы хотим изменить город Луна на Сан-Франциско, поэтому у нас нет других вариантов, кроме добавления еще одной тройки:

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

Исходя из этого, вы не можете правильно ответить на следующие вопросы:

  1. Если вы попросите указать действительный город и штат, в котором живет Луна, вы получите и Денвер, и Сан-Франциско, и их штаты.
  2. Если вы попросите последний город и штат, в котором живет Луна, вы ничего не получите, потому что тройки, определяющие связь между городами и штатами, не включены в последнюю коллекцию.

Вот краткое изложение основных вопросов:

  1. Добавление новых триплетов в базу данных: она отлично поддерживается битемпоральной функцией ML8. Вы можете вернуться назад во времени и посмотреть БД, какой она была до добавления.
  2. Удаление тройки: не поддерживается. Вы можете удалить только последние вставленные тройки из "последней" коллекции, используя temporal:document-delete. Данные есть, и вы можете запросить это. Вы можете также удалить тройки, которые хотите сохранить, так как набор троек хранится в одном документе.
  3. Обновление тройки (например, Луна переезжает в Сан-Франциско из Денвера). В идеале вы должны иметь возможность удалить старую тройку и вставить новую (по аналогии с возможностью обновления SPARQL ML8), но, поскольку удаление не поддерживается, вы получите как новые, так и старые тройки, сохраненные в / восстановленные из БД.,

Есть ли обходной путь для удаления / обновления временных троек, чтобы мы могли ответить на примеры вопросов?

1 ответ

Я думаю, что имеет смысл полагаться на системную ось вместо действительной оси. Разница заключается в том, что системная ось помогает определить, когда данные поступили в систему и когда они истекли (например, временной эквивалент удаления). Допустимая ось говорит о семантической достоверности данных. Он сообщает, когда он стал актуальным, и когда он потерял / потерял актуальность. Кроме того, системная ось управляется MarkLogic, поэтому она гарантирует, что временные версии не имеют перекрывающихся времен окончания, что, как мне кажется, является основной проблемой в приведенном выше примере.

Я не уверен, что описанный случай даже действительно требует BI-временного. MarkLogic 9 поставляется с возможностью использовать одновременный, например, используя только системную ось. Это значительно упростит обслуживание, поскольку вы можете просто пропустить действительные свойства оси, и при этом будет более надежным, поскольку вам нужно заботиться только о времени запуска системы при (временной) вставке. Срок действия предыдущих версий истекает автоматически, поскольку MarkLogic соответствующим образом обновит системное время предыдущих версий.

Я также думаю, что будет проще, если вы сгруппируете свои тройки по субъекту iri и создадите один документ для каждого субъекта iri, управляемый временно. Если вы обновите тройку определенной темы, вы можете выполнить обновление временного узла, чтобы внести соответствующее тройное изменение. Если вы сначала вставите тройку для Luna, проживающей в Денвере, а затем (временно) обновите Luna triple doc, чтобы сказать, что Luna живет в SF, более старая версия получает время окончания новой системы, предшествующее времени запуска системы самой новой версии.

Затем вы можете запускать SPARQL-запросы, ограниченные cts:collection-query('latest') получать только самые новые временные тройки, cts:lsqt-query(..) получить тройки за определенное время до LSQT или сделать что-то вручную с помощью запроса диапазона дат в свойствах времени начала и окончания системы.

НТН!

Другие вопросы по тегам