2

我有以下问题。我们使用 MarkLogic 的 OBI 框架,我在数据库中使用触发器来监控传入的传感器数据。一旦加载了新的 OBI 源,我就会检查一些东西。如果我找到一些东西,我会创建一个“警报”对象。然后我想使用该对象生成“有效负载”消息发送到移动设备......

现在触发器工作。在触发器中,我使用带有不同事务的 xdmp:eval 以确保我可以使用在相同触发器代码中创建的文档...但是如果我搜索新创建的对象,则找不到它...

我可以创建一个文档并在同一个触发代码中使用它吗?

恐怕很难在这里创建一个最小的工作示例,但这是一个尝试:

相关触发代码:

(: fire trigger ALWAYS :)
let $_ := xdmp:log(fn:concat('TP-SENSORTRIGGER-ACTION : Source ', $trgr:uri, ' triggers base rule...')) 
(: create alert object plus link to source :)
let $object-id := xdmp:eval(concat('
    xquery version "1.0-ml";
    import module namespace scl = "http://example.com/sccs/lib" at "/lib/sccss-lib.xqy";

    declare variable $source-id external;

    let $object-id := scl:create-alert-object($source-id)
    let $_ := xdmp:log("***** test *****")      
    return $object-id 
    '), (xs:QName('source-id'), $source-id),
    <options xmlns="xdmp:eval"><isolation>different-transaction</isolation></options>)
let $_ := xdmp:log($object-id)
(: create payload from alert object :)
(:let $payload := scl:create-payload-from-alert-object($object-id)
:)
let $object := obj:find-object($object-id)
let $_ := xdmp:log($object)

创建 OBI 对象的函数在一个库中。如果需要,我可以分享。我添加了一个日志行“test”和“test B”以确保我使用了正确的触发器。并确保它们在 app-specific.rb 中部署时重建。

然后从日志中很明显找不到对象:

2015-10-20 15:33:02.860 Info: example-app: ******** Ingest transform Started ***************
2015-10-20 15:33:04.196 Info: TaskServer: TP-SENSORTRIGGER /marklogic.solutions.obi/source/81a3591a-a885-4f85-a781-b066e706ff41.xml was created, start trigger action...
2015-10-20 15:33:04.291 Info: TaskServer: TP-SENSORTRIGGER-ACTION : Source /marklogic.solutions.obi/source/81a3591a-a885-4f85-a781-b066e706ff41.xml triggers base rule...
2015-10-20 15:33:07.267 Info: TaskServer: ***** test B *****
2015-10-20 15:33:07.268 Info: TaskServer: ***** test *****
2015-10-20 15:33:07.273 Info: TaskServer: 4d1fd4e4-2911-40b0-848c-ccf8eaa39229
2015-10-20 15:33:07.277 Info: TaskServer: 

触发器运行后,我当然可以从 QC 中找到 ID 为 4d1fd4e4-2911-40b0-848c-ccf8eaa39229 的对象。

所以我猜这与 MarkLogic 的事务模型有关。

那么问题又来了:为什么我在 xdmp:eval 中找不到我刚刚创建的对象?

4

1 回答 1

0

解决方案

事实证明,您必须将所有函数下游包装在 xdmp:eval() 中才能正常工作。

(: fire trigger ALWAYS :)
let $_ := xdmp:log(fn:concat('TP-SENSORTRIGGER-ACTION : Source ', $trgr:uri, ' triggers base rule...')) 
(: create alert object plus link to source :)
let $object-id := xdmp:eval(concat('
    xquery version "1.0-ml";
    import module namespace scl = "http://example.com/sccs/lib" at "/lib/example-lib.xqy";

    declare variable $source-id external;
    declare variable $actions external;
    declare variable $lastseen external;

    let $object-id := scl:create-alert-object($source-id,$actions,$lastseen)

    return $object-id 
    '), (xs:QName('source-id'), $source-id,xs:QName('actions'), $actions,xs:QName('lastseen'), $lastseen),
    <options xmlns="xdmp:eval"><isolation>different-transaction</isolation></options>)
let $_ := xdmp:log($object-id)
(: create payload from alert object :)
(:let $payload := scl:create-payload-from-alert-object($object-id)
:)
let $payload := xdmp:eval(concat('
    xquery version "1.0-ml";
    import module namespace scl = "http://example.com/sccs/lib" at "/lib/sccss-lib.xqy";

    declare variable $object-id external;

    let $payload := scl:create-payload-from-alert-object($object-id)

    return $payload 
    '), (xs:QName('object-id'), $object-id),
    <options xmlns="xdmp:eval"><isolation>different-transaction</isolation></options>)
let $_ := xdmp:log("************* PAYLOAD ****************")
let $_ := xdmp:log($payload)
(: send alert to middletier :)

let $result := xdmp:eval(concat('
    xquery version "1.0-ml";
    import module namespace scl = "http://example.com/sccs/lib" at "/lib/sccss-lib.xqy";

    declare variable $payload external;

    let $res := scl:send-alert-notification($payload)

    return $res 
    '), (xs:QName('payload'), $payload),
    <options xmlns="xdmp:eval"><isolation>different-transaction</isolation></options>)
let $_ := xdmp:log("************* RESULT ****************")
let $_ := xdmp:log($result)

这在 xdmp:eval()函数的文档中并不清楚:

" 当设置为 different-transaction 时,语句在与调用它的事务不同的事务中进行评估,从而使这些更新可用于调用语句中的后续表达式(假设调用语句是更新语句;如果调用语句不是更新,则后续表达式将在调用语句开始评估时在系统时间戳处看到数据库版本)。”

于 2015-10-26T00:49:42.890 回答