MarkLogic 日期时间使用 SQL

MarkLogic dateTime using SQL

我目前正在尝试通过 Hibernate 运行 和 运行 下的 Postgresql 驱动程序建立 ODBC 连接,以解决以下问题。

这是我的 TDE 模式之一:

<tde:template xmlns:tde='http://marklogic.com/xdmp/tde'
              xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
              xsi:schemaLocation='http://marklogic.com/xdmp/tde'>
  <tde:context>/mytable</tde:context>
  <tde:enabled>true</tde:enabled>
  <tde:rows>
    <tde:row>
      <tde:schema-name>myschema</tde:schema-name>
      <tde:view-name>myview</tde:view-name>
      <tde:columns>
        <tde:column>
          <tde:name>mycolumn</tde:name>
          <tde:scalar-type>dateTime</tde:scalar-type>
          <tde:val>mycolumn</tde:val>
        </tde:column>
      </tde:columns>
    </tde:row>
  </tde:rows>
</tde:template>

请注意,mycolumn 列的类型为 dateTime。值如下所示:2018-04-02T09:05:30

日期时间包含 'T' 并且自 xs:dateTime('2018-04-02T09:05:30') 起有效 xs:dateTime。

一个 select 查询(select 来自我的 table 的 mycolumn)成功 returns 来自此 table 的值。

但是,当我尝试使用 PostgresSql 驱动程序从 table 中读取值时,就会抛出此异常:

Caused by: java.lang.NumberFormatException: Trailing junk on timestamp: 'T09:05:30'
    at org.postgresql.jdbc.TimestampUtils.parseBackendTimestamp(TimestampUtils.java:345) ~[postgresql-42.2.2.jar:42.2.2]
    at org.postgresql.jdbc.TimestampUtils.toTimestamp(TimestampUtils.java:386) ~[postgresql-42.2.2.jar:42.2.2]
    at org.postgresql.jdbc.PgResultSet.getTimestamp(PgResultSet.java:610) ~[postgresql-42.2.2.jar:42.2.2]
    at org.postgresql.jdbc.PgResultSet.getTimestamp(PgResultSet.java:2513) ~[postgresql-42.2.2.jar:42.2.2]

我 运行 这个问题归结为以下 line,其中 Postgres 完成读取日期并且只跳过空格,但不跳过 'T' 字符。所以 Postgres 会很乐意接受 2018-04-02 09:05:30 格式的 dateTime 而不是 'T'。问题是,marklogic 没有。遗憾的是,日期时间中缺少的 'T' 不是 MarkLogic 中的有效日期时间(检查 xs:dateTime('2018-04-02 09:05:30'))。

这让我只有一个解决方案,分叉 Postgres 驱动程序源并添加代码以跳过 'T' 字符。

我还缺少其他解决方案吗?

模板值提取支持有限数量的 XPath 和转换函数。请参阅模板 API here 的详细信息。当模板引擎索引视图时,它可以索引文档值的转换。

对于您的用例,您可以配置模板视图以将 dateTime 中的 T 替换为 space。下面的代码片段只是将模板中的 <tde:val>mycolumn</tde:val> 元素替换为 <tde:val>fn:replace(mycolumn, 'T', ' ')</tde:val>。由于 PostgreSQL 要求日期时间格式与 MarkLogic dateTime 不同,您可以通过设置 <tde:scalar-type>string</tde:scalar-type> 将列索引为字符串。 tde:node-data-extract 调用应该 return 一行的字符串格式为 PostgreSQL dateTime 没有 T.

xquery version "1.0-ml";

let $template := <tde:template xmlns:tde='http://marklogic.com/xdmp/tde'
              xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
              xsi:schemaLocation='http://marklogic.com/xdmp/tde'>
  <tde:context>/mytable</tde:context>
  <tde:enabled>true</tde:enabled>
  <tde:rows>
    <tde:row>
      <tde:schema-name>myschema</tde:schema-name>
      <tde:view-name>myview</tde:view-name>
      <tde:columns>
        <tde:column>
          <tde:name>mycolumn</tde:name>
          <tde:scalar-type>string</tde:scalar-type>
          <tde:val>fn:replace(mycolumn, 'T', ' ')</tde:val>
        </tde:column>
      </tde:columns>
    </tde:row>
  </tde:rows>
</tde:template>

let $node-valid-date := <mytable><mycolumn>2018-04-02T09:05:30</mycolumn></mytable>

return tde:node-data-extract($node-valid-date, $template)