Write and read document in the same run - xquery

I am using BaseX version 9.5 and trying to ingest docs into database and read it in the same run:
let $result := for $i in 1 to 10
return
(
db:replace('test','/content/'||$i||'.xml',<test id="{$i}"></test>)
)
return
for $uris in fn:uri-collection('test')
return $uris
Currently document getting ingested into system but I am not getting the URIs of the document,
Please suggest how can I achieve this
Thanks

Related

Store unwellformed XHTML in Basex DB

I have to store XHTML which is not wellformed e.g.(<img href"tes.jpg">) so there is no closing element for element or self close.
I am using the REST service to store data into database, below is the code:
let $$DocPath:= 'D:\sample\'
for $files in file:children($DocPath)
let $filename := fn:tokenize($files,'\\')[fn:last()]
return
(
db:replace('test',('\content\'||$filename),fn:doc($files),map{'skipcorrupt' : true()}),
admin:write-log(fn:concat('Content ingested', ' ' , $filename))
)
I have used option "skipcorrupt" but it didn't work and I am getting error while ingesting content:
(Line 369): The element type "img" must be terminated by the matching end-tag "".]
Is there any option which I need to configure in the "web.xml" or ".basex" file, please suggest.
Thanks

Xquery/eXist-db - iterating over a collection +/- 3 positions from current document

In eXist-db I have hundreds of documents in /db/apps/foo/resources/documents like so:
...
BNF9992-J305-1.xml
BNF9992-J305-5.xml
BNF9992-J308-9.xml
BNF9992-J310-8.xml
BNF9992-J311-1.xml
BNF9992-J312-6.xml
BNF9992-J312-7.xml
BNF9992-J315-9.xml
BNF9992-J316-2.xml
BNF9992-J317-2.xml
BNF9992-J319-3.xml
...
Imagine I want to present to the user a list of 3 documents appearing before and after a specific document (based on alpha-numeric sort). So, my 'current document' is BNF9992-J312-7.xml, and I want to show the user something like:
BNF9992-J310-8.xml
BNF9992-J311-1.xml
BNF9992-J312-6.xml
BNF9992-J312-7.xml (current document)
BNF9992-J315-9.xml
BNF9992-J316-2.xml
BNF9992-J317-2.xml
Is there a function/method in Xquery 3.1 for iterating up/down a list of documents once they've been retrieved. The most I've been able to do is a simple retrieval of document names from a collection:
for $resource in collection("/db/apps/foo/resources/documents")
let $uri := base-uri($resource)
return util:unescape-uri(replace($uri, ".+/(.+)$","$1"), "UTF-8")
But I don't know how to iterate up and down the list from a given document.
Perhaps writing the list into nodes and applying a formula to node ordinals?
Many thanks.
If this were a list of strings $list, and the "current string" is $s, then I would do
let $i := index-of($list, $s)
return subsequence($list, $i - 3, 7)
I'm not sure whether the fact that you have a list of documents (rather than strings) changes this.

Setting collection in MarkLogic

I have a requirement where I have to set collection to the existing documents. The thing is I have around 20 million records. I am running below query from query console. It is throwing time out error.
I also tried out limit=N option in below query. At max I was able to achieve N=40000, after that it's again throwing time out error.
Please help me with any faster query or approach.
for $each in cts:uri-match("/data/employee/*")
return xdmp:document-set-collections($each, "employee")
ml-gradle has OOTB support for this, no code needed. See https://github.com/marklogic-community/ml-gradle/wiki/DMSDK-Tasks#trying-it-out and look at "mlAddCollections".
Batching is the right option to perform this type of task. Use xdmp:spawn-function() function to put multiple tasks at a time on the task server. You just need to indentify the number of records which your query can finish within 10 minute or 1 hr as you required.
For example, if query can execute 5000 records within 10 minute:
let $total-records := xdmp:estimate(collection())
let $batch-size := 5000
let $pagination := 0
for $records in 1 to fn:ceiling($total-records div $batch-size )
let $start := fn:sum($pagination + 1)
let $end := fn:sum($batch-size + $pagination)
let $_ := xdmp:set($pagination, $end)
return
xdmp:spawn-function
(
function(),
for $each in cts:uri-match("/data/employee/*")[$start to $end]
return xdmp:document-set-collections($each, "employee")
)

Marklogic How to change directory name

How to update directory from "/Collections/" to "/CollectionsCount/" in Marklogic
for $each in xdmp:directory("/collections/", "infinity")
return xdmp:node-uri($each)
result found:
/collections/Count2017-08-25.xml
/collections/Count2017-08-27.xml
/collections/Count2017-08-26.xml
/collections/Count2017-08-28.xml
I would like to update directory to become "/collectionsCount/" what function do I use. Thanks in advance.
/collectionsCount/Count2017-08-25.xml
/collectionsCount/Count2017-08-26.xml
....
Directories are a construct based on a document's URI, so in order to change the directories, you will need to delete the old documents and insert new ones at new URIs (using the new directory prefix in place of the old one).
for $each in xdmp:directory("/collections/", "infinity")
let $old-uri := $each/xdmp:node-uri(.)
let $permissions := xdmp:document-get-permissions($old-uri)
let $collections := xdmp:document-get-collections($old-uri)
let $quality := xdmp:document-get-quality($old-uri)
let $properties := xdmp:document-properties($old-uri)
let $new-uri := concat('/collectionsCount/', substring-after($old-uri, '/collections/'))
return (
xdmp:document-insert($new-uri, $each, $permissions, $collections, $quality),
xdmp:document-set-properties($new-uri, $properties),
xdmp:document-delete($old-uri))
Edit: Updated to include #hunterhacker's suggestion to propagate document metadata. Note that I intentionally left out assigning the new document to the old document's forest, since in most cases I assume it's better to let the database decide.

How to get more information about an image stored in eXist-db

I can’t figure out how to get more information in one run.
For example, I would like to do some basic math for later operations (typically, scaling).
This:
import module namespace image = "http://exist-db.org/xquery/image";
let $img := util:binary-doc('/db/apps/tested-bunny/data/deepspace.jpg')
let $img-width := image:get-width($img)
let $img-height := image:get-height($img)
return
($img-width, $img-height)
… returns only the width.
This:
import module namespace image = "http://exist-db.org/xquery/image";
let $img := util:binary-doc('/db/apps/tested-bunny/data/deepspace.jpg')
let $img-width := image:get-width($img)
return
($img-width, image:get-metadata($img, true()))
… returns only the width.
This:
import module namespace image = "http://exist-db.org/xquery/image";
let $img := util:binary-doc('/db/apps/tested-bunny/data/deepspace.jpg')
return
(image:get-width($img) * image:get-height($img))
… returns nothing.
Is the function somehow limited in getting more information at once?
As #joewiz found, this is a bug in the version 3.0.RC1 of eXist-db. In the latest nightly build it works. Solved.

Resources