Document-Based Storage is an architectural abstraction in the Nuxeo Platform that allows the storage of documents in a document-oriented store, for instance NoSQL databases.
The Nuxeo Platform supports the following MarkLogic version:
MarkLogic 8.0
Installation
Nuxeo Package Installation
This addon requires no specific installation steps. It can be installed like any other package with nuxeoctl command line or from the Update Center.
Databases
In order to run Nuxeo on MarkLogic, you need to have two databases. One for documents and another one for modules.
You can achieve that with MarkLogic administration GUI under Databases
.
By default Nuxeo stores its information in the database nuxeo
. By convention we use nuxeo-modules
as modules database.
XDBC Server Installation
You need to create a new XDBC App Server linked to the nuxeo
database and nuxeo-modules
modules, as described in the MarkLogic documentation. Main installation information is:
- Set
/
value in root input. - Choose a server name and a port (for example 8010).
- Select the
nuxeo
database in the database input. - Select the
nuxeo-modules
database in the modules input.
User permissions
Roles
In order to secure your database access, you can create new roles to protect it. Under Security/Roles, create:
A new role named nuxeo-reader
, with:
- Roles: rest-reader
- Execute Privileges: xdbc:eval, xdbc:eval-in, xdbc:invoke, xdbc:invoke-in, xdbc:spawn, xdbc:spawn-in, xdmp:value, xdmp:with-namespaces
A new role named nuxeo-writer
, with:
- Roles: rest-writer, nuxeo-reader
- Execute Privileges: any-collection, any-uri, xdbc:insert, xdbc:insert-in
- Default permissions: add nuxeo-reader with read capability, nuxeo-writer with update capability and nuxeo-writer with insert capability
Users
Under Security/Users, create a new user to use in MarkLogic connector to access to your database through XDBC app server.
Choose a username and password, and add nuxeo-reader
and nuxeo-writer
in Roles section.
Modules
The MarkLogic connector needs some modules in order to properly work. These modules are used to update documents, lock/unlock them or search them (NXQL search).
A module is basically a regular document stored in the module database, here nuxeo-modules
.
You can use the qconsole to insert properly modules in the modules database, you can access it here: http://[IP]:8000/qconsole/
Below the steps to insert modules:
- Create a new Query in qconsole
- Declare a variable containing the content of
xqy
file, like:let $module := '...'
. - Declare a variable containing right permissions to execute module, like:
let $permissions := ( xdmp:permission("[PERMISSION]", "execute") )
. - Finally, insert the module in database, like:
return xdmp:document-insert("[PATH]", text { $module }, $permissions)
.
You should have for each modules something like this:
let $module :=
'
[MODULE_CONTENT]
'
let $permissions := (
xdmp:permission("[PERMISSION]", "execute")
)
return xdmp:document-insert("[PATH]", text { $module }, $permissions)
See the matrix above for variables:
Module | Content | Permission | Path |
---|---|---|---|
patch.xqy | Here | nuxeo-writer |
/ext/nuxeo/patch.xqy |
set-lock.xqy | Here | nuxeo-writer |
/ext/nuxeo/set-lock.xqy |
remove-lock.xqy | Here | nuxeo-writer |
/ext/nuxeo/remove-lock.xqy |
extract.xqy | Here | nuxeo-reader |
/ext/nuxeo/extract.xqy |
Configuration
Once you installed the Nuxeo MarkLogic addon, set up the access to the MarkLogic server in nuxeo.conf
. The following properties are available:
nuxeo.marklogic.host
: The MarkLogic server, defaults tolocalhost
nuxeo.marklogic.port
: The MarkLogic XDBC App Server port, defaults to8010
nuxeo.marklogic.user
: The MarkLogic user to login to App Server, defaults tonuxeo
nuxeo.marklogic.password
: The user password, defaults topassword
nuxeo.marklogic.ssl
: The SSL switcher, defaults to false, set it to true to enable ssl encryption to your MarkLogic server
The package installation added the marklogic
template to your existing list of templates (nuxeo.templates
) in nuxeo.conf
.
You must keep the template corresponding to your SQL database in nuxeo.templates
, because the SQL database may still be used for other things (directories, audit, etc.). For instance you could have:
nuxeo.templates=postgresql,marklogic
or
nuxeo.templates=default,marklogic
Range Index Configuration
In order to properly work, MarkLogic needs a range element index for each elements you want to compare using <
, <=
, >=
or >
in a NXQL query.
We also use range index in order to query some elements. To leverage on range indexes, we need to use a different kind of MarkLogic function during NXQL -> MarkLogic query conversion.
In order to enable this behavior, you need to add the Nuxeo element in repository configuration.
You need to use range-element-index
to declare a Nuxeo element to be queried with the range index behavior. The element name in repository configuration are the Nuxeo ones, for example we declare ecm:parentId
in the repository configuration and we create ecm__parentId
in MarkLogic. Below the default configuration of repository:
<extension target="org.nuxeo.ecm.core.storage.marklogic.MarkLogicRepositoryService" point="repository">
<repository name="test" label="MarkLogic Repository">
...
<range-element-indexes>
<range-element-index type="string">ecm:id</range-element-index>
<range-element-index type="string">ecm:parentId</range-element-index>
<range-element-index type="string">ecm:ancestorIds</range-element-index>
<range-element-index type="string">ecm:versionSeriesId</range-element-index>
<range-element-index type="string">ecm:proxyTargetId</range-element-index>
<range-element-index type="string">ecm:proxySeriesId</range-element-index>
<range-element-index type="string">ecm:racl</range-element-index> <!-- Technical element -->
<range-element-index type="string">ecm:name</range-element-index>
<range-element-index type="string">ecm:primaryType</range-element-index>
<range-element-index type="string">ecm:lifeCycleState</range-element-index>
<range-element-index type="string">dc:title</range-element-index>
<range-element-index type="dateTime">dc:created</range-element-index>
<range-element-index type="dateTime">dc:modified</range-element-index>
<range-element-index type="string">rend:renditionName</range-element-index>
<range-element-index type="dateTime">rend:modificationDate</range-element-index>
<range-element-index type="dateTime">rend:sourceModificationDate</range-element-index>
<range-element-index type="string">collectionMember:collectionIds</range-element-index>
<range-element-index type="dateTime">nt:dueDate</range-element-index>
<range-element-index type="dateTime">dc:issued</range-element-index>
<range-element-index type="string">webc:name</range-element-index>
</range-element-indexes>
...
</repository>
</extension>
Here's a list of basic Nuxeo elements needing a range element index:
Nuxeo Element (NXQL name) | MarkLogic Element | Scalar Type |
---|---|---|
ecm:id (ecm:uuid) | ecm__id | string |
ecm:parentId | ecm__parentId | string |
ecm:ancestorId | ecm__ancestorIds__item | string |
ecm:versionSeriesId (ecm:versionVersionableId) | ecm__versionSeriesId | string |
ecm:proxyTargetId | ecm__proxyTargetId | string |
ecm:proxyVersionableId | ecm__proxyVersionSeriesId | string |
ecm:__read_acl | ecm__racl | string |
ecm:name | ecm__name | string |
ecm:primaryType | ecm__primaryType | string |
ecm:currentLifeCycleState | ecm__lifeCycleState | string |
dc:title | dc__title | string |
dc:created | dc__created | dateTime |
dc:modified | dc__modified | dateTime |
rend:renditionName | rend__renditionName | string |
rend:modificationDate | rend__modificationDate | dateTime |
rend:sourceModificationDate | rend__sourceModificationDate | dateTime |
collectionMember:collectionIds | collectionMember__collectionIds__item | string |
nt:dueDate | nt__dueDate | dateTime |
dc:issued | dc__issued | dateTime |
webc:name | webc__name | string |
created | created | dateTime |
replaced | replaced | dateTime |
version-id | version-id | long |
begin | begin | dateTime |
end | end | dateTime |
length | length | long |
In order to create these indexes, go to your MarkLogic server configuration, under your database you'll find Element Range Indexes
. In this section you can create a range element index for each elements with the correct scalar type. Leave namespace uri
empty, set range value positions
to false, and invalid values
to ignore.
Storage Restrictions
Due to the nature of DBS, we use a transaction model equivalent to READ UNCOMMITTED, which means that a transaction may read data written but not yet committed by another transaction.
Full-text configuration is disabled, you should use Elasticsearch with a suitable full-text configuration.
Not Yet Implemented
The following features are planned for a later Nuxeo version but are not implemented currently:
- tags aren't supported (NXP-17670)
- querying n-th element of a list is not supported (NXP-21187)
- NOT NXQL constraints such as
item/*
can return false positive (NXP-21184) - Range index querying is not supported on a date element