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)
我目前正在尝试通过 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)