Reputation: 3138
I am trying to create a script to add Fields on MarkLogic Database with Admin API. I have created following functions to perform this task:
declare function local:createField($config as element(configuration), $server-config as element(http-server))
{
let $dbid := xdmp:database(fn:data($server-config/database))
let $addField :=
let $fieldspec := admin:database-field("VideoTitle1", fn:false())
return admin:save-configuration(admin:database-add-field($config, $dbid, $fieldspec))
return "SUCCESS"
};
declare function local:createFieldPath($config as element(configuration), $server-config as element(http-server))
{
let $dbid := xdmp:database(fn:data($server-config/database))
let $addPath :=
let $fieldpath := admin:database-field-path("/Video/BasicInfo/Title", 1.0)
return admin:save-configuration(admin:database-add-field-paths($config, $dbid, "VideoTitle1", $fieldpath))
return "SUCCESS"
};
declare function local:createFieldRangeIndex($config as element(configuration), $server-config as element(http-server))
{
let $dbid := xdmp:database(fn:data($server-config/database))
let $addRange :=
let $rangespec := admin:database-range-field-index("string","VideoTitle1", "http://marklogic.com/collation/",fn:false() )
return admin:save-configuration(admin:database-add-range-field-index($config, $dbid, $rangespec))
return "SUCCESS"
};
But I am getting error:
[1.0-ml] ADMIN-BADPATHFIELDTYPE: (err:FOER0000) Incorrect field:
the field VideoTitle1 already has include-root.
In /MarkLogic/admin.xqy on line 5255
In database-check-path-field(<configuration/>, xs:unsignedLong("12095791717198876597"), "VideoTitle1")
$config := <configuration/>
$database-id := xs:unsignedLong("12095791717198876597")
$field-name := "VideoTitle1"
$field := <field xmlns="http://marklogic.com/xdmp/database" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><field-name>VideoTitle1</field-name><include-root>false</include...</field>
$field-path := ()
I am running complete script through QC and my MarkLogic version is "7.0-1". I have created Element Range Index, Attribute Range Index successfully by the script. But for this I am getting error.
Error description says that field has include-root. But, I am keeping it false()
admin:database-field("VideoTitle1", fn:false())
Is I am using wrong function or missed something?
Please help.
Upvotes: 0
Views: 160
Reputation: 7842
If you're trying to set up an entire database you're usually better off using the packaging API and services: https://developer.marklogic.com/learn/packaging-tutorial gives a tour of the configuration manager web UI, and then there is a guide, an XQuery API, and a REST API.
That said let's try to debug. It's difficult to debug your error message because the variable names and line numbers in the error message don't match up with your sample code. For example the stack trace has $database-id
but your code has $dbid
. A test case needs to be reproducible.
However I notice that you aren't calling the right function to construct your field configuration. If you want to use paths, say so up front using https://docs.marklogic.com/admin:database-path-field — not admin:database-path
. The error message could use some work: it should be something more like "Incorrect field: the field VideoTitle1 is not a path field".
If you really want to stick with the admin API for this, I recommend changing your code so that you only call admin:save-configuration
once. That's more efficient, and more robust in the face of any need to restart. One way to arrange this would be for each of your function calls to take a $config as element(configuration)
param and return a new element(configuration)
with the changes. Another method is to have a module variable $CONFIG as element(configuration)
and mutate it with xdmp:set
. Take a look at https://stackoverflow.com/a/12252515/908390 for examples of both techniques.
Here's a working version of your code:
import module namespace admin="http://marklogic.com/xdmp/admin"
at "/MarkLogic/admin.xqy";
declare function local:createField(
$config as element(configuration),
$server-config as element(http-server))
as element(configuration)
{
let $dbid := xdmp:database(fn:data($server-config/database))
let $fieldspec :=
admin:database-path-field(
"VideoTitle1",
admin:database-field-path("/Video/BasicInfo/Title", 1.0))
return admin:database-add-field($config, $dbid, $fieldspec)
};
declare function local:createFieldRangeIndex(
$config as element(configuration),
$server-config as element(http-server))
as element(configuration)
{
let $dbid := xdmp:database(fn:data($server-config/database))
let $rangespec :=
admin:database-range-field-index(
"string",
"VideoTitle1",
"http://marklogic.com/collation/",
fn:false())
return
admin:database-add-range-field-index(
$config, $dbid, $rangespec)
};
let $cfg := admin:get-configuration()
let $fubar := <http-server><database>test</database></http-server>
let $_ := xdmp:set($cfg, local:createField($cfg, $fubar))
let $_ := xdmp:set($cfg, local:createFieldRangeIndex($cfg, $fubar))
return admin:save-configuration($cfg)
Upvotes: 3
Reputation: 20414
Not a direct answer, but why reinvent a wheel that other have already invented. There are several solutions that can help deploy database settings and more. One of them is Roxy:
https://github.com/marklogic/roxy
Roxy provides a full framework for managing a MarkLogic project. You can find docs and tutorials on the wiki of the github project.
Another, less intrusive solution could be to configure your databases once, and then use the built-in Configuration Manager (http://host:8002/nav/) to export your database settings, and use the export to import the settings elsewhere.
HTH!
Upvotes: 1