Transactions 标记逻辑删除>;插入>;伙伴关系就新文件采取行动
请参阅下面的更新 我有以下问题:我们正在将(数百万)文档(tweets)收集到ML中,在insert中,我们有一个cpf作业,为每个文档创建元数据。更精确的是,它根据位置(如果存在位置或坐标)添加地理标记 现在我们有了一个数据库,它一直在收集推文,而地理标记器没有激活。我们希望通过删除并重新插入尚未具有适当元数据geotag元素的每个文档来处理此cpf作业中存储的tweet。 然后cpf完成它的工作,并对“新”文档进行地理标记 我们已经编写了以下代码来删除和插入文档,但是我们得到了一个XDMP-CONFLICTUPDATES错误。我一直在阅读有关交易的书籍,并尝试了几种方法,即“;”诀窍。在xdmp:eval中包装,或在xdmp:spawn的两个单独函数调用中拆分delete和insert 还是不走运 spawn-rename.xqyTransactions 标记逻辑删除>;插入>;伙伴关系就新文件采取行动,transactions,xquery,marklogic,Transactions,Xquery,Marklogic,请参阅下面的更新 我有以下问题:我们正在将(数百万)文档(tweets)收集到ML中,在insert中,我们有一个cpf作业,为每个文档创建元数据。更精确的是,它根据位置(如果存在位置或坐标)添加地理标记 现在我们有了一个数据库,它一直在收集推文,而地理标记器没有激活。我们希望通过删除并重新插入尚未具有适当元数据geotag元素的每个文档来处理此cpf作业中存储的tweet。 然后cpf完成它的工作,并对“新”文档进行地理标记 我们已经编写了以下代码来删除和插入文档,但是我们得到了一个XDMP-
xquery version "1.0-ml";
declare namespace j = "http://marklogic.com/xdmp/json/basic";
declare variable $to_process external;
declare function local:document-rename(
$old-uri as xs:string, $new-uri as xs:string)
as empty-sequence()
{
(:xdmp:set-transaction-mode("update"),:)
xdmp:eval(xdmp:document-delete($old-uri)),
(:xdmp:commit():)
let $permissions := xdmp:document-get-permissions($old-uri)
let $collections := xdmp:document-get-collections($old-uri)
return xdmp:document-insert(
$new-uri, doc($old-uri),
if ($permissions) then $permissions
else xdmp:default-permissions(),
if ($collections) then $collections
else xdmp:default-collections(),
xdmp:document-get-quality($old-uri)
)
};
for $d in map:keys($to_process)
let $rename := local:document-rename($d, map:get($to_process,$d))
return true()
要为我们使用的特定文档集运行作业,请执行以下操作:
xquery version "1.0-ml";
declare namespace j = "http://marklogic.com/xdmp/json/basic";
declare namespace dikw = 'http://www.example.com/dikw_functions.xqy';
import module namespace json = "http://marklogic.com/xdmp/json" at "/MarkLogic/json/json.xqy";
let $foo := cts:uris((),(), cts:not-query(cts:element-query(xs:QName("j:dikwmetadata"), cts:element-query(xs:QName("j:data"), cts:and-query(())))))
let $items := cts:uri-match("/twitter/403580066367815680.json") (:any valid uri or set of uris:)
let $map := map:map()
let $f := doc($items[1])
let $id := $f/j:json/j:id/text()
let $oldUri := xdmp:node-uri($f)
let $newUri := fn:concat("/twitter/", $f/j:json/j:id/text(), ".json")
let $put := map:put($map,$oldUri,$newUri)
let $spawn := xdmp:spawn("/Modules/DIKW/spawn-rename-split.xqy", (xs:QName("to_process"), $map))
return ($oldUri, " - ", $newUri)
问题:
如何设置代码,使其在单独的事务中首先删除地图中的文档,然后再将其插入,以便cpf可以进行地理标记
更新 根据grtjn的评论(到目前为止是thx!) 我尝试重写代码,如下所示:
xquery version "1.0-ml";
declare namespace j = "http://marklogic.com/xdmp/json/basic";
let $entries := cts:uri-match("//twitter/*")
let $entry-count := fn:count($entries)
let $transaction-size := 100 (: batch size $max :)
let $total-transactions := ceiling($entry-count div $transaction-size)
(: set total documents and total transactions so UI displays collecting :)
(: skip 84 85
let $set-total := infodev:ticket-set-total-documents($ticket-id, $entry-count)
let $set-trans := infodev:ticket-set-total-transactions($ticket-id,$total-transactions)
:)
(: create transactions by breaking document set into maps
each maps's documents are saved to the db in their own transaction :)
let $transactions :=
for $i at $index in 1 to $total-transactions
let $map := map:map()
let $start := (($i -1) *$transaction-size) + 1
let $finish := min((($start - 1 + $transaction-size),$entry-count))
let $put :=
for $entry in ($entries)[$start to $finish]
(: 96
let $id := fn:concat(fn:string($entry/atom:id),".xml")
:)
let $id := fn:doc($entry)/j:json/j:id/text()
return map:put($map,$id,$entry)
return $map
(: the callback function for ingest
skip 101 let $function := xdmp:function(xs:QName("feed:process-file"))
:)
let $ingestion :=
for $transaction at $index in $transactions
return true()
return $ingestion (: this second return statement seems odd? :)
(: do spawn here? :)
(: xdmp:spawn("/modules/spawn-move.xqy", (xs:QName("to_process"), $map)) :)
现在我很困惑,为了让这个“有效”,我需要添加上一个似乎不正确的报税表。此外,如果按原样运行查询并返回超时错误,我还试图弄清楚到底发生了什么。
我想首先了解交易的实际用途。
对不起,我的无知,但似乎执行(相对简单的)任务重命名一些文件看起来不是那么简单
为完整起见,请在此处输入my spawn-move.qry:
xquery version "1.0-ml";
declare namespace j = "http://marklogic.com/xdmp/json/basic";
declare variable $to_process external;
declare function local:document-move(
$id as xs:string, $doc as xs:string)
as empty-sequence()
{
let $newUri := fn:concat("/twitter/", $id, ".json")
let $ins := xdmp:document-insert($newUri,fn:doc($doc))
let $del := xdmp:document-delete($doc)
return true()
};
for $d in map:keys($to_process)
let $move := local:document-move($d, map:get($to_process,$d))
return true()
在您的示例中,似乎您正试图在同一步骤中删除文档并将其写入同一URI。您可以通过xdmp:commit()解决这个问题。但是,另一种解决方案是,首先在一批中重命名文档(将它们全部移到一边),然后在完成后,将它们分批移回原处。我怀疑您实际上不是在重命名文档,而是在重新插入它们。如果
$old uri
与$new uri
相同,则您引用的重命名
函数不会预料到这种情况,并且会执行多余的文档删除
。在delete周围添加if
,在这种情况下跳过它。保留所有其他内容以保留权限、集合、质量和属性。文档插入
功能已经在实际插入之前删除了预先存在的文档。另见:
<>你也可以考虑添加一点逻辑来做多个产卵。理想情况下,根据硬件和林配置,您希望以100到500个文档为一批重新插入文档。有一个很好的例子说明了如何在github上的infostudio收集器中计算“事务”(从第80行开始):
<>您也可以考虑在这些事务中做地理工作,而不是将其委托给CPF。但是,如果您的地理位置查找涉及到外部调用,例如可能很慢,那么请坚持使用CPF
嗯 实际上,如果您已将CPF管道配置为处理诸如creates之类的更新(这是默认配置),则只需重新插入文档即可:
xdmp:document insert($d,doc($d))thx用于响应,我尝试了xdmp:commit()(请参见我尝试的第一个代码,但注释为in out),但这不起作用,它需要一个分号来结束事务,而您会遇到各种我不理解的问题。我正在为你的第二个方向努力,但我觉得这似乎很缓慢?另外,cpf过程似乎非常缓慢。有没有加快cpf的提示?可能会帮助您理解
xdmp:commit
和分号.thx grtjn,我有两个用例,一个确实只是重新插入现有文档,另一个是我在错误的uri中插入了500.000个文档,从“/twitter/”开始,而不是“/twitter/”,因此查看“/twitter/”的cpf作业遗漏了这些文档。我正在寻找处理这些问题的方法。一般来说,我不知道如何在ml中完成这类工作,而不会遇到查询超时等问题。当指针指向第80行时,我无法理解插入和运行它所需的内容,以便一次处理500000个文档。@hugo koopmans将第80行复制到104行,定义一个包含所有URI的变量$entries(您有$foo/$items),使用条目数定义变量$entry count,将$max替换为100(这是您的批处理大小),跳过第84/85/96/101行,编辑第97行,将$entry作为键和一个伪值放在映射中,并在第104行之后添加您的spawn。这样,您可以在spawn之前跳过计算$newURI,但最好在spawed任务中改为这样做。