Most applications implemented on previous versions of MarkLogic will run either without modifications or with very minor modifications in MarkLogic 9. This section summarizes product changes that can cause compatibility issues for applications developed using previous releases and includes the following topics:
For CentOS 8, MarkLogic has a dependency on libnsl.so.1()
. You must install this library when using CentOS 8. You can either rely on yum
to pull in the dependency automatically, or install it manually.
The Hadoop Connector was deprecated starting with MarkLogic release 9.0-12 and is removed from the product in MarkLogic 9.0-13.
The ValueIterator
interface used to represent sequences of value in MarkLogic 8 has been replaced by the new Sequence
interface. A Sequence
is a JavaScript Iterable object. All functions which previously operated on or returned a ValueIterator
now use a Sequence
instead.
In many cases, this change is transparent to your code. However, code that depends on the following ValueIterator
properties and methods must be changed:
for..of
loop to iterate over a Sequence
. Use fn.head if you just want to pick off the first or only value in a Sequence.Sequence
multiple times.For more details, see Sequence in the JavaScript Reference Guide and Sequence in the MarkLogic Server-Side JavaScript Function Reference.
In MarkLogic 9, when you create a new database, the stemmed searches
property is off
by default. In MarkLogic 8 and earlier, the default is basic
.
In MarkLogic 9, when you create a new database, word searches
are enabled by default. In MarkLogic 8 and earlier releases, word searches
were disabled by default.
To achieve the pre-MarkLogic 9 default behavior, configure your database to turn off stemmed searches
and set word searches
to true
.
These changes only affect databases you create after upgrading to MarkLogic 9. Databases that exist when you upgrade will retain their previous settings.
In MarkLogic 9, a fresh install of MarkLogic 9 will enable the triple index and collection lexicon for all databases. Databases that exist when you upgrade to MarkLogic 9 will retain their previous settings. Any new databases created after upgrading to MarkLogic 9 will have the triple index and collection lexicon enabled.
The XCC .NET interfaces have been removed from MarkLogic. Current users of XCC .NET are encouraged to use the REST Client API to create equivalent interfaces. For details, see the REST Application Developer's Guide.
MarkLogic 9 introduces the following changes to the behavior of semantic queries:
The triple index and SPARQL engine have been changed in MarkLogic 9. Now as part of a query, two triples are considered equal if their subjects, predicates, and objects compare as equal with the SPARQL =
operator.
Previously, these triples would be treated as two different, non-identical triples:
sem:triple(xs:anyURI("http://a"), xs:anyURI("http://b"), xs:anyURI("http://c")), sem:triple("http://a", "http://b", "http://c").
In MarkLogic 9, values of type xs:string
and xs:anyURI
can compare equal if they have the same lexical form according to the SPARQL =
operator. This functionality is called D-entailment (D as in datatype). The two triples in the example are now considered to be the same, and the de-duplication process removes the duplicate. If you return frequencies, you would see the second triple show up as one extra in the frequencies.
Also note that the query may return either sem:triple(xs:anyURI("http://a"), xs:anyURI("http://b"), xs:anyURI("http://c"))
, or sem:triple("http://a", "http://b", "http://c")
as the result since they are considered equal.
The forest ID options for the sem:sparql function, which were part of MarkLogic 7, were removed in MarkLogic 8, but their functionality was kept for backwards compatibility. In MarkLogic 9, the forest ID option will no longer work with sem:sparql.
During a rolling upgrade, while the cluster is in a mixed mode (not all hosts committed to the new version yet) the triple count of semantice triples may be increased after inserting the same data twice. During a rolling upgrade, the MarkLogic 9 triple index is not able to return triples in the correct order for MarkLogic 8 semantics. For this situation to occur, a user would need to have multiple triples that are identical except for the types of the values.
The database parameter max merge size
defaults to 48 GB (49152 MB) for new databases created in MarkLogic 9. Previously, the default was 32 GB. Existing databases will keep whatever max merge size
setting is configured after upgrading to MarkLogic 9. The new setting reflects advances in storage systems and should be appropriate for most databases.
In MarkLogic 9, index reference resolution in range index construction, query constructors, and lexicon operations will now succeed in some cases that would have thrown an XDMP-RIDXNOTFOUND
error in previous releases. If the index reference contains enough information to unambiguously match an existing index, MarkLogic will now do so. Previously, MarkLogic assumed default values for some missing index attributes, resulting in an error.
Code that previously succeeded will continue to do so. Some code that would previously have gotten an error will no longer do so.
For example, suppose you define a geospatial element range index on element xs:QName("coords")
with type long-lat-point
and coordinate system wgs84
, and then refer to the index by just the element QName (cts:element-geospatial-values(xs:QName("coord")
). Previously, the reference would have been an error because the default point type (point
) would have been assumed. Now, the reference resolves correctly as long as there is not a second geospatial element range index on the same QName with different coordinate system or point type.
When an ambiguous range index reference is detected, MarkLogic 9 throws one of the new exceptions XDMP-RIDXAMBIGUOUS
(range index) or XDMP-GIDXAMBIGUOUS
(geospatial index).
In MarkLogic 9 the default tokenization and stemming libraries have been changed for all languages (except English tokenization). Consequently, some tokenization and stemming behavior will change between MarkLogic 8 and MarkLogic 9. We expect that, in most cases, stemming and tokenization will be more precise in MarkLogic 9.
If you upgrade to MarkLogic 9 from an earlier version of MarkLogic, your installation will continue to use the legacy stemming and tokenization libraries as the language baseline. Any fresh installation of MarkLogic will use the new libraries. You can change the baseline configuration using admin:cluster-set-language-baseline.
Changing the baseline requires a cluster-wide restart and a reindex to avoid stemming and tokenization anomalies.
Use of the legacy libraries is deprecated. These libraries will be removed from MarkLogic in a future release.
Unless you use the legacy language baseline, reindexing is required for content in the following languages:
For other languages (except English), you might be able to avoid incompatibilities depending on the nature of your queries, but reindexing is still strongly recommended.
Tokenization and stemming are significantly different for Japanese. Tokenization is significantly different for Chinese (both simplified and traditional). The impact on other languages is more nuanced, but should lead to better results, overall. You might observe some relevance score changes on stemmed searches due to the higher degree of precision. If you require low-level details about the impact on a specific language and you have an active maintenance contract, you can contact MarkLogic Technical Support.
For more details on incompatibilities related to the changes to stemming and tokenization, see the Knowledge Base article entitled MarkLogic Server v9 Tokenization and Stemming from MarkLogic Technical Support, available at the following URL:
https://help.marklogic.com/knowledgebase/article/View/484
For more information about the new tokenization and stemming support, see New Stemming and Tokenization.
In MarkLogic 9, the SQL DESCRIBE
function is not supported. MarkLogic does support DESCRIBE
queries over ODBC, but not from xdmp:sql()
.
MarkLogic 9 now provides application-specific access to logging. Instead of logging all errors to ErrorLog.txt
, the xdmp:log function now writes to an app-server-specific log file - for example 8000_ErrorLog.txt
or 8020_ErrorLog.txt
. Anything event running on the task server is logged to TaskServer_ErrorLog.txt
. The ErrorLog.txt
file is now for MarkLogic system logging only.
Splitting the log files in this manner enables custormer log files (which could potentionally contain confidential information) to be separated from system log files. This helps ensure the privacy of customer data when they interact with Support and use the new Telemetry feature.
In a Unix environment you can watch the multiple log files using something like this:
tail -f /path/file1 /path/file2 etc.
The classification of some symbols has changed for purposes of tokenization, including the symbols in the following table. These changes can affect search results.
The userid
parameter has been removed from xdmp:user-last-login. In MarkLogic 8 the xdmp:user-last-login took one parameter (userid
). If the userid
was different from the current user, the function returned an empty sequence. If the userid
was the same as that of the current user, it only returned the last login information.
In MarkLogic 9 the function does not take a parameter. The xdmp:user-last-login function only returns the last login information for the current user.
These two functions, xdmp:document-insert and xdmp:document-load, have significantly changed interfaces in MarkLogic 9. The interfaces will still work for purposes of backward compatibility, but are no longer documented.
In MarkLogic 8, search:parse returned the XML serialization of a cts:query by default. You could also explicitly select this return type by specifying cts:query as the value of the $output
parameter.
In MarkLogic 9, if you explicitly specify cts:query as the value of the $output
parameter, you will now get a cts:query object instead of a serialized query. The default return type from search:parse is unchanged.
If your code explicitly sets the output type to cts:query and passes the output of search:parse straight through to functions such as search:resolve or cts:search, no code changes are required.
If your code explicitly sets the output type to cts:query and then transforms or traverses the output query XML, then you must change your code to use the new schema-element(cts:query) for the $output
parameter of search:parse.
For example, the following call generates the XML serialization of a cts:query in MarkLogic 9:
search:parse("cat AND dog", (), "schema-element(cts:query)")
The defined default search behavior for the Java, Node.js, and REST Client APIs is unfiltered search unless you override the default with your own options. Prior to MarkLogic 9, this default behavior was not honored when you used the Client APIs to interact with MarkLogic through the pre-defined App Server on port 8000.
As of MarkLogic 9, searches via the Client APIs on port 8000 will default to unfiltered search. To get the old behavior, use query options that explicitly specify filtered search.
In MarkLogic 8, the query constructed by the XQuery function cts:json-property-scope-query and the Server-Side JavaScript function cts.jsonPropertyScopeQuery matched if it's criteria query matched anywhere within the configured scope. In MarkLogic 9, the behavior has changed for certain JSON property scope queries where the scope property value is an array of objects.
The behavior has changed for searches that have the following characteristics:
query
parameter of the property scope query is an and-query. Such a scope query effectively finds co-occurrences of matches to the and-query criteria within the specified scope. Given this setup, in MarkLogic 9, the query only matches if all the sub-queries of the and-query occur in the same array item. In MarkLogic 8, the query matches even when the and-query matches occur in different array items. All other forms of JSON property scope query are unchanged.
This change makes it possible to construct a JSON property scope query that constrains matches to occurrences with a single array item. In MarkLogic 8, this was not possible.
This change also affects the container-query
element of a structured query and QBE container queries.
The following example query is of the form affected by this change. It finds co-occurences of prop1 with value value1 and prop2 with value2 within the scope of root. (The and-query criteria can be arbitrarily complex.)
If you search the following documents with the preceding query, you get the results shown. The JSON properties that match the and-query criteria are shown in bold.
Document (1) does not match in MarkLogic 9 because both and-query criteria are not satisfied in the same array item. Document (2) matches in MarkLogic 9 because both and-query criteria are satisfied in the same array item. The Document (3) results are unaffected because the value of the root property is not an array of objects.
You can restore the MarkLogic 8 behavior by using an and-query of multiple JSON property scope queries. For example, the following query matches Document (1) in MarkLogic 9:
To ensure the modified queries match only when the and-query matches occur in the same instance of the scope property (root in the examples), wrap it in a JSON property scope query on the parent parent property. For example:
MarkLogic 9 introduces the following backward incompatible changes to the REST Client API.
The previously deprecated /keyvalue
is no longer available. That is, the method GET /v1/keyvalue
is no longer available.
To perform similar operations, use the /search
service with a structured query or combined query, or the /qbe
service.
When you specify multiple collections through the collection request parameter of the following methods, they are now OR related:
The new behavior is consistent with the semantics of cts:collection-query and the structured query collection-query
.
To get AND semantics, construct your own and-query
of collection URIs as part of a structured or combined query, or by defining a constraint in your query options.
The new behavior differs from previous behavior in the following way:
In MarkLogic 9, when you write documents with the REST API using PUT v1/documents, the documents have the union of the following permissions:
In MarkLogic 10, when you write documents with the REST API using PUT v1/documents, the documents have the union of the following permissions:
In other words, what has changed is that the rest-reader and rest-writer convenience roles no longer have any permissions on a document unless one of the following is true:
Since the rest-writer convenience role default permissions grant reader permission to the rest-reader role and update permissions to the rest-writer role, documents written by a user who has the rest-writer convenience role are readable by users with the rest-reader role and writable by users with the rest-writer role.
The expected behavior is for explicit permissions to replace rest-reader and rest-writer permissions. This change has been made to MarkLogic 10 to provide more control over the security model.
The default value of the repair
parameter in the Document Management PUT /v1/documents function has changed in the following way:
MarkLogic 9 introduces the following backwards incompatible changes to the Java Client API:
Most of the previously deprecated packages, interfaces, classes, and methods of the Java Client API have been removed. The following table lists what has been removed and provides guidance for modifying your code.
In the table below, c.m.c. is an abbreviation for com.marklogic.client..
The JAR file for the Java Client API is now named marklogic-client-api-
version.jar
. Previously, the name was java-client-api-
version.jar
. For example, the JAR file name for version 3.0.6 is java-client-api-3.0.6.jar
, but the JAR file name for version 4.0.1 is marklogic-client-api-4.0.1.jar
.
The Maven artifact ID for the Java Client API is now marklogic-client-api
instead of java-client-api
. Update your build dependency configuration files, such as pom.xml
or build.gradle
, accordingly.
The Logback library is no longer included in the Java Client API distribution. Logging is now off by default. To re-enable logging, include Logback or another slf4j JAR in your classpath.
The following incompatible changes have been made to the Node.js Client API:
The method DatabaseClient.documents.remove
previously returned an object with both a "uri" property and a "uris" property that served the same purpose. The "uri" property has been removed. The return value now has the following form:
{ "uris":[uri1, uri2, ...], "removed":true }
The value of the "uris" property is now always an array. Previously, if you passed in just a single string as input, remove
returned just the URI string, rather than an array of one item.
Previously, DatabaseClient.transactions.open
returned a transaction id string by default, and you could use the withState
parameter to request a transaction object instead. The use of the string form was deprecated as of MarkLogic 8.
As of MarkLogic 9 and Node.js Client API v2.0.0, DatabaseClient.transactions.open
defaults to returning a transaction object.
To force the previous behavior, set withState
to false
when creating a transaction. This setting is deprecated and will be removed in a future release.
Previously, the slice clause on search (queryBuilder.slice
) accepted a one-based starting position and a page length:
slice(oneBasedStart,PageLength)
As of MarkLogic 9 and Node.js Client API v2.0.0, queryBuilder.slice
clause behaves like Array.prototype.slice
. That is, it takes a zero-based starting position and the (zero-based) position after the last result to be retrieved. For example, the following slice call returns the first 5 results:
... .slice(0,5) ...
Also, you could previously use slice(0)
to suppress the return of result documents and just retrieve an abbreviated summary. Now, you must include both the start and end positions for the same effect. For example: slice(0,0)
.
To restore the legacy behavior, use marklogic.setSliceMode
. Note, however, that this form is deprecated and will be removed in a later release.
The semantics of valuesBuilder.slice are unchanged. This function still accepts as 1-based starting position and a page length.
The introduction of support for double precision coordinates in MarkLogic 9 means that some geospatial operations may return different results than in the past.
Previously, geospatial region accessor functions such as the XQuery function cts:point-latitude or the Server-Side JavaScript function cts.pointLatitude always returned float values. As of MarkLogic 9, these functions can return either single or double precision values, depending on the governing coordinate system. If you do not use a double precision coordinate system, you should not notice a difference.
The following functions are affected.
For more details, see How Precision Affects Geospatial Operations in the Search Developer's Guide.
The version of MarkLogic's C++ User-Defined Function (UDF) interface has been incremented to accomodate the following changes:
marklogic::Point
class now accepts and returns longitude and latitude values as doubles instead of floats. You must recompile your UDF plugins for use with MarkLogic 9. UDFs from an earlier version of MarkLogic will not work in a mixed cluster prior to commiting the new version. During a rolling upgrade, you must finish the upgrade and then recompile your UDFs for use with MarkLogic 9.
In MarkLogic 9, the SUSE Linux Enterprise Server operating system is not supported. If you are using this discontinued platform, you will need to migrate your environment to a supported platform. For details on supported platforms, see Supported Platforms.
In MarkLogic 9, the Solaris operating system is not supported. If you are using this discontinued platform, you will need to migrate your environment to a supported platform. For details on supported platforms, see Supported Platforms.
Support for the Nagios monitoring plugin has been discontinued in MarkLogic 9.
You can create your own MarkLogic monitoring integration using the MarkLogic REST Management API; for details see the Monitoring MarkLogic Guide.
MarkLogic does not endorse or support any particular 3rd party monitoring integrations. However, the MarkLogic open source community includes integrations with 3rd party monitoring platforms such as New Relic and App Dynamics. For more details see:
In the future, Ops Director will be MarkLogic's fully integrated monitoring solution. For details, see the Ops Director Guide.
The Application Builder and Information Studio applications have been removed from MarkLogic. The info and infodev APIs remain, but they are deprecated; for details, see info and infodev APIs Deprecated.
An Application Builder application deployed on MarkLogic 8 should continue to work after the upgrade to MarkLogic 9. We do not support any mechanism to support redeploying such an app against a MarkLogic 9 node. The methods and modules needed for this process have been removed.
Porting an Application Builder application running in MarkLogic 7 to MarkLogic 9 is not supported by MarkLogic Server. If you have an active maintenance contract, you can contact MarkLogic Technical Support for guidance in porting this application.
As of MarkLogic 9, you can create a database without an associated schemas database. Earlier versions of MarkLogic required you to specify a schemas database when creating a new database. This change has no impact on users creating databases through the Admin API. However, this change affects the database creation page of the Admin Interface as follows:
The Admin Interface no longer automatically selects the pre-defined Schemas database as the schemas database when you create a database through the UI. Instead, you must explicit select a schemas database or else you will create a database with no associated schemas database.
Depending on the uses to which you put the database, some operations might fail if there is no associated schemas database. For example, features such as temporal document management and template driven extraction require a schemas database to be associated with the content database.
This section describes some changes related to external security support. You should be aware of these changes, but they do not introduce incompatibilities or necessitate a change to your application.
In MarkLogic 9, you can log into port 7001 on an LDAP account when internal security on appserver port 7001 is set to true or false. In previous versions of MarkLogic, you can only log into port 7001 on an LDAP account if internal security on appserver port 7001 is set to false.
As of MarkLogic 9, you can assign multiple external security objects to an App Server. When there are multiple external security objects assigned, a MarkLogic user is authenticated and assigned to an external security based on the order in which the external security objects are assigned. In previous version of MarkLogic, you could only assing one external security object to an App Server.
If internal security is enabled for an App Server, then when a user attempts to authenticate with MarkLogic, MarkLogic first checks to see if the user is in the security database. If so, then MarkLogic verifies the credentials against the security database. When this verification fails, the behavior of MarkLogic 8 and earlier versions differs from the behavior of MarkLogic 9 as follows:
Thus, when internal security is enabled, there can be cases where a login will succeed in MarkLogic 9 that would have failed with earlier versions. The behavior is unchanged if there are no external security objects assigned to the App Server or internal security is disabled.
In MarkLogic 9, a number of REST Management API methods have been deleted and their functionality has been moved elsewhere. The following table lists the deleted methods and the new alternative.
Endpoint Deleted in 9.0 | Alternative |
---|---|
DELETE /manage/v2/credentials |
DELETE /manage/v2/credentials/properties |
GET /manage/v2/credentials |
GET /manage/v2/credentials/properties |
PUT /manage/v2/credentials |
PUT /manage/v2/credentials/properties |
GET /manage/v2/databases/{id|name}/sub-databases |
GET /manage/v2/databases |
POST /manage/v2/databases/{id|name}/sub-databases |
POST /manage/v2/databases |
GET /manage/v2/databases/{id|name}/super-databases |
GET /manage/v2/databases |
POST /manage/v2/databases/{id|name}/super-databases |
POST /manage/v2/databases |
DELETE /manage/v2/databases/{sub-id-or-name}/super-databases/{super-id-or-name} |
DELETE /manage/v2/databases/{id|name} |
GET /manage/v2/databases/{sub-id-or-name}/super-databases/{super-id-or-name} |
GET:/manage/v2/databases/{id|name}/properties |
DELETE /manage/v2/databases/{super-id-or-name}/sub-databases/{sub-id-or-name} |
DELETE /manage/v2/databases/{id|name} |
GET /manage/v2/databases/{super-id-or-name}/sub-databases/{sub-id-or-name} |
GET:/manage/v2/databases/{id|name}/properties |
Configuration packages created with the Packaging REST API and/or with the Configuration Packaging XQuery library module are not compatible with the new configuration format introduced in MarkLogic release 9.0-5.
These configuration packages cannot be used with the CMA REST API and/or with the Configuration Management API XQuery/JavaScript library modules.
Version 4.1.1 of the Java Client API introduces the following incompatibilities with earlier Java Client API versions:
This change does not affect you if you do not connect to MarkLogic through a load balancer or if you do not use the Data Movement SDK (DMSDK) feature of the Java Client API.
You must change the configuration of any DatabaseClient
objects used to connect to MarkLogic through a load balancer on behalf of a Data Movement SDK job. The following changes apply:
GATEWAY
when configuring a DatabaseClient.FilteredForestConfiguration
to configure connections through a load balancer.For more details, see Working with a Load Balancer in the Java Application Developer's Guide.
The API trgr:triggers-change-modules-database()
only takes two parameters in 9.0-11.
1. the old database as xs:anyAtomicType
. This can be an ID unsignedLong
or a name xs:string
2. the new database as xs:anyAtomicType
. This can be a database's ID unsignedLong
or a database's name xs:string.
For more details and sample code, see our API documentation.
These Entity Services features are deprecated and will be removed in a future release.
Instance functions: The instance
functions, like es.instanceConverterGenerate or es:instance-converter-generate are deprecated.
Model functions: Of the es.model/es:model
functions, only es:model-validate and es.modelValidate are used. The other model
functions are deprecated.
Attachment functions: The attachment
functions, like es:add-attachments and es.addAttachments
are deprecated.
Init functions: The init
functions, like es:init-instance are deprecated.
Version translation functions: The version translation
functions, like es:version-translator-generate and es.versionTranslatorGenerate are deprecated.
Utility functions: The utility
functions es:extract-array and es:with-namespace are no longer used and have been deprecated.
Starting in MarkLogic 9.0-9, ORDER-BY
ordering on NULL is set to NULLS LAST
. This changes default behavior for nulls in query results and therefore may cause backwards incompatibility for certain queries (unless the Optic Nulls Smallest On
trace event is turned on).
The following incompatibilities exist between MarkLogic 9.0-5 and MarkLogic 9.0-6:
As of MarkLogic 9.0-6, parsing of XML documents with an XML declaration that explicitly specifies XML version 1.1 (version="1.1") enforces the XML 1.1 character set. Consequently, you can now create content containing characters not accepted by XML 1.0.
Characters in the XML 1.1 restricted character ranges must be given as character entities. This enforcement applies to the following character ranges:
The following character ranges that were previously disallowed are now accepted.
Serializing content that contains characters allowed by XML 1.1 but not XML 1.0 can cause problems for client layers that cannot handle the XML 1.1 character set. You can control whether to serialize XML as version 1.0 or 1.1 by setting the output version in your App Server output options, using methods such as the following:
Groups
> yourGroup > App Servers
> yourAppServer > Output Options
.output-version
property to 1.0.The following incompatibilities exist between MarkLogic 9.0-4 and MarkLogic 9.0-5:
The Configuration Manager tool is deprecated starting with MarkLogic 9.0-5 and removed from MarkLogic Server in version 10.0-3.
As of MarkLogic 9.0-5, if you are using the Hortonworks Data Platform (HDP) with the following MarkLogic technologies, you must use HDP v2.6.
This change affects only database configuration that define a geospatial region index.
MarkLogic 9.0-5 introduces support for a tolerance option on geospatial region queries. As a consequence, if you use geospatial region indexes, your region queries might not be accurate until you reindex. This is applicable whether or not you take advantage of the new tolerance option.
As of MarkLogic 9.0-5, MarkLogic uses the coordinate system default tolerance when evaluating a geospatial region query. Previously, MarkLogic used the coordinate system minimum tolerance.
Consequently, some region queries might not give the same results after upgrading to MarkLogic 9.0-5. Use the tolerance option to adjust your region queries, if necessary.
To learn more about tolerance, see Understanding Tolerance in the Search Developer's Guide.
This change only affects users of the REST, Java, and Node.js Client APIs who use the return-query
query option and generate a search response summary in JSON.
In prior versions of MarkLogic, the return-query
query option returned a serialized JSON structured query in the query
property of the search response in JSON, but a serialized cts:query in an XML search response. As of MarkLogic 9.0-5, return-query
always generates a serialized cts:query. The serialized JSON representation can be passed to cts:query
or cts.query
to reconstruct an in-memory query object on MarkLogic, just as you can with the XML serialization.
This change will not affect you if you do not use a JSON search response, do not use return-query
, or do not have code that depends on the serialization produced by return-query
.
The following incompatibilities exist between MarkLogic 9.0-3 and Marklogic 9.0-4:
MarkLogic 9.0-4 introduces support for salting in the generation of masking values by the mask-deterministi
c redaction function. This means the same text redacted with mask-deterministic
in earlier versions of MarkLogic will not produce the same masking value by default when redacted using MarkLogic 9.0-4.
To preserve the previous behavior, modify your mask-deterministic
rules to set the salt
and extend-salt
options to an empty value.
For more details, see mask-deterministic in the Application Developer's Guide.
The following incompatibilities exist between MarkLogic 9.0-2 and MarkLogic 9.0-3:
MarkLogic Server 9.0-3 authenticates using both a client certificate and a username/password. This provides a greater level of security, by requiring that the user provide a client certificate that matches the specified user. In MarkLogic 9.0-2, if the password is incorrect, but the user has the correct client certificate, and the ssl require client certificate is false, authentication will succeed. In MarkLogic 9.0-3 if the password is incorrect, but the user has the correct client certificate and ssl require client certificate is false, authentication fails.
The ssl require client certificate is an appserver configuration. With the appserver, there are different authentication options: basic, digest, application-level, certificate, and kerberos-ticket. This change only applies to basic, digest or application-level authentication. This behavior only happens when ssl require client certificate is set to false
In previous versions, MarkLogic would accept username/password for any internal user, once MarkLogic verified that certificate was signed by the selected CA (certificate authority). MarkLogic 9.0-1 and 9.0-2 authentication is restricted to an internal user with a matching common name (CN). In MarkLogic 9.0-3, the username does not need to match the common name (CN).
The behavior in MarkLogic 9.0-3 is the same as it is in MarkLogic 8.0. For more information, see the Certificate topic in the Security Guide.
The XCC method ContentSource.newSession
has been extended to include a new overload that accepts a char[]
value for the password parameter, rather than a String
, to enable more secure handling of passwords.
As a consequence of this change, passing null
in the password parameter of newSession
now results in a compile time error because the compiler cannot determine the correct overload without type information. Use a typecast to disambiguate your call.
Prior to MarkLogic 9.0-3, the server did not check the nonce for digest authentication. In MarkLogic 9.0-3, the server checks the nonce, verifies that it is a valid nonce, and verifies that the URI in the Authorization header is same as the request URI.
In order to support 1-click deployment in AWS Marketplace, MarkLogic 9 AMIs have data volume pre-configured (device on /dev/sdf
). To be compatible with 1-click AMIs, new CloudFormation templates are released on https://developer.marklogic.com/products/cloud/aws. To upgrade existing clusters, new 1-click compatible CloudFormation templates are required.
If custom templates or scripts are used, additional steps may be required to handle blank data volume that is part of the new marketplace AMIs. Please find more details about the upgrade procedure on https://developer.marklogic.com/products/cloud/aws.
As of MarkLogic 9.0-4, the map:new function retains any input key-value pair whose value is an empty sequence. Previous versions of MarkLogic 9 and versions of MarkLogic 8 prior to 8.0-7 discarded such key-value pairs.
map:keys(map:new(map:entry("noval",()))) (: Now returns "noval". Previously, returned an empty sequence. :)
The following incompatibilities exist between MarkLogic 9.0-1 and MarkLogic 9.0-2:
The -tolerate_errors
option of the mlcp import
command is deprecated. As of MarkLogic 9.0-2, mlcp ignores this option and always behaves as if -tolerate_errors
is set to true. The option will be removed in a future release.
In previous versions of MarkLogic, calling jsearch.facets always produced a JSON object for each facet, with object properties of the form facetValue:
count. This structure prevented proper sorting of facet values.
As of MarkLogic 9.0-2, the structure of each facet is an array of arrays instead of a JSON object if and only if you include an explicit orderBy
clause in your facet definition. If you do not use orderBy, the output is unchanged.
For more details, see Sorting Facet Values with OrderBy in the Search Developer's Guide.
In MarkLogic 9.0-1, if you use xdmp.x509CertificateGenerate to generate a certificate, and the configuration object includes array-valued properties, the array values were encoded as a single string. As of MarkLogic 9.0-2, the array type is preserved. This change applies to any Relative Distinguished Names (RDNs) within a Distinguished Name (DN), such as the issuer
and subject
DNs.
For example, in the following snippet, the issuer.organizationName
property has an array value.
var certObj = { version: "2", serialNumber: "BA0195369CD6B679", issuer: { countryName: "US", stateOrProvinceName: "CA", localityName: "San Carlos", organizationName: ["MarkLogic", "Mark Logic"], organizationalUnitName: "Eng", emailAddress: "jdonner@marklogic.com", commonName: "JGD Certificate Authority", },... }; var privateKey = ...; xdmp.x509CertificatExtract( xdmp.x509CertificateGenerate(certObj, privateKey) );
If you round trip the generated certificate through xdmp.x509CertificateExtract, you will see the following output for issuer.organizationName
in MarkLogic 9.0-1 vs MarkLogic 9.0-2.
// Marklogic 9.0-1 organizationName: "[\"MarkLogic\", \"Mark Logic\"]" // MarkLogic 9.0-2 and later organizationName: ["MarkLogic", "Mark Logic"]
If you do not have a certificate containing a multi-valued property, you will not notice any difference in behavior.
Previously, the slice clause on values queries (valuesBuilder.slice
) accepted a one-based starting position and a page length:
slice(oneBasedStart,PageLength)
As Node.js Client API v2.0.3, the valuesBuilder.slice
clause behaves like Array.prototype.slice
. That is, it takes a zero-based starting position and the (zero-based) position after the last result to be retrieved. For example, the following slice call returns the first 5 results:
... .slice(0,5) ...
To restore the legacy behavior, use marklogic.setSliceMode
. Note, however, that this form is deprecated and will be removed in a later release.
Previously, setting the XQuery prolog option xdmp:update to false caused MarkLogic to automatically detect whether a module should be evaluated as an update or a query transaction.
As of MarkLogic 9.0-2, setting the option to false tells MarkLogic to treat the code as a query transaction. This could cause your program to get an error if you explicitly set the option to false and your code performs an update operation.
The new auto option value is equivalent to the previous behavior of false.
As of version 4.0.2, the Java Client API uses OkHttp as its HTTP client for communicating with MarkLogic over HTTP. This change should be transparent to most applications, but imposes the following backward incompatibility on applications that customize their HTTP configuration:
Attaching a configurator based on HttpClientConfigurator
to a DatabaseClientFactory
object no longer has any effect on the HTTP configuration. Use the new com.marklogic.client.extra.okhttpclient.OkHttpClientConfigurator
interface instead. The HttpClientConfigurator
interface is deprecated and will be removed in a future release.
This section describes the incompatibilites between MarkLogic 7 and MarkLogic 8. This is here just for convenience; for the MarkLogic 8 Release Notes, see docs.marklogic.com/8.0/guide/relnotes. The following are the incompatibilies:
MarkLogic 9 includes Native JSON support. In MarkLogic 7, there was support for JSON via a set of libraries to convert between JSON and XML. If you are using the MarkLogic 7 JSON support, you will have to migrate your code to use the native JSON support. This should end up being more efficient, but will require you to do some minor code changes. This section lists the incompatibilites related to working with JSON documents:
In previous versions of MarkLogic, you can load JSON documents into MarkLogic using either the REST Client API or the Java Client API. When you do so, the documents are transformed and stored as XML, but are still queryable as and returned as JSON. In MarkLogic 8 this XML facade is no longer needed, and the REST and Java Client APIs in MarkLogic 8 do not do the translation to the XML facade anymore. Therefore, if you have any document that were loaded as JSON in MarkLogic 7 and earlier, you must convert those document to native JSON in order to query them as JSON using the REST API.
To help with the conversion, MarkLogic supplies a set of conversion scripts. These scripts do not handle every case, and for any case it does not handle you will have to convert the documents some other way. Because the conversion scripts do not handle all cases, it is very important to do a backup of your database before attempting the conversion. The scripts are located in the Samples/migrate-scripts
directory under the MarkLogic installation directory (/opt/MarkLogic
on Linux, c:/Program Files/MarkLogic
on Windows, and ~/Library/MarkLogic
on Mac OS). The scripts require bash and curl, and on Windows platforms they also require cygwin.
For more details, see the <marklogic-dir>/Samples/migrate-scripts/README
file.
Generally, the conversion scripts perform the following:
json-key
to json-property
.The scripts do not upgrade your application code. The types of things you will need to change in your application include:
json-key
and anything in the http://marklogic.com/xdmp/json/basic
namespace. For more details see Search, Java, REST: json-key Is Now json-property in Options and Structured Query./v1/keyvalues
endpoint for key/value searches over JSON.The basic steps to upgrade your MarkLogic 7 or earlier JSON to native JSON in MarkLogic 8 are as follows:
Samples/migrate-scripts/conf
directory. This files have details about your configuration and index settings.Samples/migrate-scripts/migrate
script.If you have problems upgrading your application and you have an active maintenance contract, you can contact MarkLogic Technical Support.
MarkLogic 7 had a primitive to convert an XQuery string to an unquoted String called json:unquotedString
. In MarkLogic 8, that function is no longer available because it is no longer needed, as MarkLogic 8 has much more extensive support for JSON. For details on working with JSON in MarkLogic, see Working With JSON in the Application Developer's Guide.
In MarkLogic 8, the xdmp:to-json function returns a document-node()
; previously, it returned a string. If you have code that expects a JSON string, you might need to modify your code to perform XPath on the document-node()
to get the JSON node (which will serialize into a string); depending on what your code does, you might or might not need to do this. For example:
(: 7.0 :) xdmp:to-json(("a",fn:false())) => ["a",false] (: 8.0 :) xdmp:to-json(("a",fn:false()))/node() => ["a",false]
The json:transform-to-json function uses xdmp:to-json, so it also returns a document-node()
in MarkLogic 8.
All occurrences of json-key
in query options and structured query are now json-property
. If you use the constructs listed below to search JSON documents by key/property name, you will need to modify your query options (search:options
, in XML) or structured queries.
The following query options are affected. For details, see search:search or Appendix: Query Options Reference in the Search Developer's Guide.
The following structured query components are affected. For more details, see the structured query Syntax Reference in the Search Developer's Guide.
The corresponding Java Client API structured query builder method name has also changed. StructuredQueryBuilder.JSONKey
is now StructuredQueryBuilder.JSONProperty
.
Previously, you could specify a language when ingesting JSON documents. This was only possible because JSON documents were represented internally as XML.
This parameter is now deprecated and will be ignored when present. This affects the following interfaces:
JSONDocumentManager.setLanguage
and JSONDocumentManager.getLanguage
are deprecated. Calling setLanguage
has no effect.This section applies to applications that use the Java Client API or REST Client API patch (partial update) feature on JSON documents.
Previously, JSONPath was the default path language for identifying the target of update operations in a JSON patch. XPath is now the default path language for both XML and JSON patches.
Use of JSONPath is now deprecated. To convert your JSON patches to use XPath expressions instead of JSONPath, see Traversing JSON Documents Using XPath in the Application Developer's Guide.
To continue using JSONPath, you can explicitly override the default path language in one of the following ways:
pathlang
property as the sibling of the top level patch
property. For example:{ "pathlang": "jsonpath", "patch": [ ... ] }
Raw patches are used by POST:/v1/documents
and can be used with the Java Client API method DocumentManager.patch
.
DocumentPatchBuilder.pathLanguage
. to set the path language to JSONPath, as shown in the following example:DocumentPatchBuilder patchBldr = docMgr.newPatchBuilder(); patchBldr.pathLanguage(PathLanguage.JSONPATH);
The native JSON document model imposes some new restrictions on partial updates to JSON documents. Therefore, some patch operations that were previously supported will now be rejected or produce different results. For details, see Limitations of JSON Path Expressions in the REST Application Developer's Guide and Traversing JSON Documents Using XPath in the Application Developer's Guide.
For example, you cannot construct patch path expressions that address anonymous nodes. In the JSON document model, object nodes and array nodes are anonymous. The name in a property name-value pair addresses the value(s), not the containing node.
This means you cannot use last-child position to insert a new property or value under the root node of a document or in an array because the parent node is anonymous and cannot be selected by the context expression of the insert operation. Similarly, you cannot address an array node that is nested inside another array ([1, [2, 3], 4]
) because it is unnamed.
You can no longer replace an entire property (name-value pair) in a single patch replace
operation for the same reason. To replace a property, you must delete it and then insert a new one.
This section applies to REST Client API and Java Client API applications that use content transformations, resource service extensions, and other server-side code to manipulate the XML representation of JSON documents.
Previously, content transformations, resource service extensions, and other server-side code manipulated JSON content as XML in the http://marklogic.com/xdmp/json/basic
namespace. Now, such code must operate on JSON document nodes instead of XML.
For example, previously, the JSON data { "key": "value" } was represented in the database as XML of the following form, and this is what your server-side transforms and extensions worked with:
<json type="object" xmlns="http://marklogic.com/xdmp/json/basic"> <key type="string">value</key> </json>
Thus, to access the value of the key property in XQuery, you could use a path expression like this following:
$someDocument/json:json/json:key
With a native JSON document you reference the same data using the following path expression:
$someDocument/key
You should understand the native JSON document model before rewriting your code. For details, see Working With JSON in the Application Developer's Guide.
This change may affect applications that use QBE to search JSON documents using the Java Client API or REST Client API.
Previously, you could construct a QBE that included a word or value query explictly scoped to an array item or the . Now, it is not possible to distinguish between an array item and a property value.
For example, given a document with the following context:
{ "notArray": "blue", "array": ["azure", "blue"] }
Previously, the following QBE would only match the occurence of the value "blue"
in the "array"
property. Now it matches both the occurrence in "array"
and the occurrence in "notArray"
.
{"$query": [ {"$value": ["blue"]} ] }
This is because array nodes are unnamed in the native JSON document model, so they cannot be explicitly identified in a QBE.
This difference only applies to applications using field range queries or field value queries on JSON documents.
JSON and XML are not indexed in exactly the same way. Some of the indexing differences affect the behavior of field range queries and field value queries over JSON. Since JSON documents were previously stored as XML, this means your field range queries and field value queries over JSON may behave differently.
For example, previously you could construct a field value query for John Smith that would match the following document by defining a field on the name
property that excluded the middle
property.
{ "name": { "first": "John", "middle": "NMI", "last": "Smith" }
This was possible because the document was represented as XML and the text nodes in the field were concatenated together so that the field value in the above document was John Smith. In native JSON documents, this concatenation does not occur, and the values of the equivalent field are John and Smith. To get the same effect now, you would have to use a construct such as a near query.
For more details, see Creating Indexes and Lexicons Over JSON Documents and How Field Queries Differ Between JSON and XML in the Application Developer's Guide.
MarkLogic 8 introduces a number of new and changed Semantic features. This section describes those and includes the following changes that might cause incompatibilites:
In MarkLogic 8, the signature of sem:sparql has changed for the last parameters. The fourth parameter is now a sem:store*
, where previously there where two parameters at the end, one to specify a cts:query
and another to specify the forest ID. The old signature is still available, but is deprecated. If you have any code from MarkLogic 7 that uses the fourth or fifth arguments to sem:sparql, it will still work in MarkLogic 8, but you should migrate that code to use the new signature using sem:store as the fourth parameter.
In MarkLogic 8, sem:sparql-values now serializes a string as a cts:word-query when used as part of an argument. In other words, string values will be passed as cts:query
arguments. This is a change from MarkLogic 7.
The sem:sparql-values function no longer accepts forest-id
as an option. This is an incompatibility with MarkLogic 7 functionality.
The sem:sparql-triples
function has been deprecated in favor of sem:in-memory-store in MarkLogic 8. See documentation for details - Querying Triples in Memory in the Semantics Developer's Guide.
In MarkLogic 8, graph documents containing metadata are created when triples are ingested, whether they are ingested using SPARQL Update, mlcp, or SPARQL endpoints over REST. These named graphs inherit the permissions of the user, unless specified as part of the ingest process. The graph permissions are stored along with other metadata in the graph document.
When loading triples with mlcp, if the output-permissions
parameter is set when loading RDF, the graph will inherit the default permissions just as it would in a sem:sparql-update operation. If the output_collection
parameter is set when loading RDF, the graph document is only created for the first collection specified (because a managed triple can only belong to one graph).
In an upgraded system, graph metadata for managed triples created in MarkLogic 7 will be created the first time you add triples to the graph or modify triples in the graph. The graph will either have the user's permissions or the permissions specified as part of the operation. Make sure the document permissions of documents containing managed triples created in MarkLogic 7 are passed into sem:sparql-update as default-permissions
to ensure the graph metadata created is consistent with the permissions for existing managed triples created in MarkLogic 7.
This section covers the incompatibilites for the REST API between MarkLogic 7 and MarkLogic 8. that are not related to JSON. If you work with JSON documents using the REST Client API or Java Client API, you should also see JSON Related Incompatibilities.
This section covers the following incompatibilities:
You cannot use earlier versions of the Java Client API with MarkLogic 8. Update your application to use version 3.0 or later.
In MarkLogic 7, App Servers that are REST API Instances used a different URL rewriter than in MarkLogic 8. In MarkLogic 8, the App Server is configured to use the declarative rewriter. If you had not modified anything in your REST API Instance App Server setup, the upgrade to MarkLogic 8 will reconfigure your App Server to use the new rewriter. If, however, you have modified something in setup to use a different rewriter, then you will have to make similar changes to the new setup (or consider not using those changes in the REST API Instance). For details on the declarative rewriter, see xWeb Services in the Application Developer's Guide.
In MarkLogic 7, the POST method of a resource service extension was always executed in update mode. In MarkLogic 8, POST methods in a single-statement transaction are executed in query mode. However, within a multi-statement transaction, they are in update mode. The new way is safer because, generally speaking, if a function is not doing an update, it is much more efficient for it to run as a query.
If you have a resource service extension that requires the transaction mode to be update, you need to modify the extension code to add an annotation to the function to explicitly force it into update mode. For example, to modify an extension that is a GET, add an annotation like the following to your get function:
declare %rapi:transaction-mode("update") function testrstxn:get( $context, $params) { <Your code goes here> };
The annotation %rapi:transaction-mode("update")
forces the function to run as an update. For details, see Controlling Transaction Mode in the REST Application Developer's Guide.
Previously, performing a bulk read by retrieving all documents that match a query would return a 404 Not Found response status if no documents matched the query. As of MarkLogic 8, such a request returns a 200 OK status with an empty response body.
This change applies to the following methods, when the Accept header is set to multi-part/mixed and the request does not ask for a search result summary in addition to the matching documents.
For more details on these interfaces, see Reading Multiple Documents Matching a Query in the REST Application Developer's Guide.
The changes in this section might affect your application if either of the following is true:
MarkLogic 8 introduces the following incompatible changes to error reporting for users of the
In previous versions, the default format for error messages returned by the REST Client API was XML, and you could change it by setting the error-format
instance configuration property. As of MarkLogic 8, the default error format for new REST instances is JSON. You can now specify the format when you create the REST instance, and you can subsequently change it using the Admin Interface, admin:appserver-set-default-error-format, or the REST Management API.
This change has the following implications:
setErrorFormat
and getErrorFormat
methods of com.marklogic.client.admin.ServerConfigurationManager
have been removed. Set the error message format when creating the REST instance instead./v1/config/properties/error-format
methods are no longer available. Set the error message format when creating a REST instance instead.error-format
XML element or JSON property in the payload to PUT /v1/config/properties.error-format
XML element or JSON property. This is an attribute of the App Server.To set the error format when creating an instance, set the error-format
configuration property. For details, see Creating an Instance in the REST Application Developer's Guide.
The error detail returned by the REST Client API has changed in the following ways. For examples of the new format, see Error Reporting in the REST Application Developer's Guide.
<error-response>
element in the namespace http://marklogic.com/xdmp/error
. Previously, it was an <error/>
element in the namespace http://marklogic.com/rest-api
.errorResponse
. Previously, it was error
. Child property names that previously used dashes to separate words now use camel case. For example, message-code
is now messageCode
and status-code
is now statusCode
.Resource service extensions and transformations previously reported errors to the client using RESTAPI-EXTNERR
and could specify a response payload in JSON or XML. The expected error response content type was controlled by a caller supplied parameter. This parameter is now ignored, and you should use RESTAPI-SRVEXERR
instead of RESTAPI-EXTNERR
. Your payload must be compatible with the MIME type expected by the caller, which can vary, so it is best to restrict the error detail to text. For details, see Reporting Errors in the REST Application Developer's Guide.
This topic applies to applications that use the Java Client API class KeyValueQueryDefinition
or the REST Client API method GET:/v1/keyvalue
. These interfaces are now deprecated.
You can use Query By Example (QBE) or structured query to perform the same kind of search.
For example, to search for a JSON property named author with the value Mark Twain, use a QBE such as the following:
{ "$query": { "author": "Mark Twain" } }
The following is a similar search for an XML element:
<q:qbe xmlns:q="http://marklogic.com/appservices/querybyexample"> <q:query> <author>Mark Twain</author> </q:query> </q:qbe>
With structured query, use value-query
or container-query
.
For details, see the following references:
RawQueryByExampleDefinition
or StructuredQueryBuilder
in the Java Client API javadoc.Previously the transaction ids created using DatabaseClient.openTransaction
(Java) or POST /v1/transactions (REST) were of the form hostId_transactionId
. The hostId
segment has now been dropped.
As long as your application treats the transaction id as a black box, this change is transparent.
This change only affects Java Client API and REST Client API applications that use multi-statement transactions and share the resulting transaction id across multiple users.
Previously, it was possible to create a multi-statement transaction as one MarkLogic user and then perform operations within the transaction as another user. This is no longer possible. Now, all operations within a transaction must be performed as the same user who created the transaction.
Previously, using QueryManager.search
with a Query By Example (QBE) automatically returned results in the same format as the query. That is, XML results were returned for an XML QBE, and JSON results were returned for a JSON QBE. Now, you must explicitly request JSON.
For example, if the qbe
variable in the following statement contains a JSON QBE, then previously you would receive JSON results. Now, you will receive XML by default, instead.
queryMgr.search(qbe.newStringHandle()).get();
To achieve the same result as before, explicitly set the format on the result handle to JSON. For example:
queryMgr.search(qbe.newStringHandle().withFormat(Format.JSON)).get();
MarkLogic 8 includes an enhancement to Document Library Services to make it significantly faster for large DLS repositories. This enhancement requires some metadata changes to the documents under DLS control.
If you have any DLS repositories created in MarkLogic 7 or earlier, you must first set compatibility mode for your repository, and then upgrade the documents in the repository, and finally set the repository to upgraded. The upgrade process will touch all of the documents under DLS control, so it will take a while, depending on the size of your DLS application. If you do not perform at least the first part of this upgrade, DLS functions might produce incorrect results in MarkLogic 8.
Because this is an upgrade that touches a large number of documents, MarkLogic strongly recommends that you first back up your database and that you thoroughly test your process on a development system before upgrading your production DLS repository.
To upgrade existing DLS repositories, perform the following steps:
admin
role, set compatibility mode for your DLS repository by running the following XQuery against your DLS database (for example, in Query Console):xquery version "1.0-ml"; import module namespace dls = "http://marklogic.com/xdmp/dls" at "/MarkLogic/dls.xqy"; dls:set-upgrade-status(fn:false())
admin
role, run the following XQuery against your DLS database (for example, in Query Console):xquery version "1.0-ml"; (: This starts a task which will run for a time proportional to the number of documents you have under DLS control. The function returns immediately though. It is safe to rerun this function if it is stopped or fails for any reason such as a system restart. :) import module namespace dls = "http://marklogic.com/xdmp/dls" at "/MarkLogic/dls.xqy"; dls:start-upgrade()
If you stop the upgrade (for example, if the server is restarted or if there are errors in the upgrade that you have fixed), you can restart the upgrade at any time by running the above query.
upgrade-task-status.xml
document, ad in the following XQuery:xquery version "1.0-ml"; (: this document is updated every few minutes to show the progress of the upgrade :) fn:doc("http://marklogic.com/dls/upgrade-task-status.xml")
xquery version "1.0-ml"; import module namespace dls = "http://marklogic.com/xdmp/dls" at "/MarkLogic/dls.xqy"; dls:latest-validation-results()
dls:validation-status
. When the value of that element is completed, the process is complete
.admin
role or a user with the dls-admin
role:xquery version "1.0-ml"; import module namespace dls = "http://marklogic.com/xdmp/dls" at "/MarkLogic/dls.xqy"; dls:set-upgrade-status(fn:true())
Once the process is successful, you can use DLS as usual.
It is also possible to run DLS in compatibility mode without running the upgrade on the repository (by not running the upgrade portion of the above procedure), but MarkLogic strongly recommends performing this upgrade procedure. If you have any problems or questions and you have an active maintenance contract, you can contact MarkLogic Technical Support.
MarkLogic 8 Linux platforms now require Red Hat 6, and will no longer work on Red Hat 5; they will fail to install on Red Hat 5. So if you are running MarkLogic 7 on Red Hat 5, you will have to migrate that environment to Red Hat 6 in order to use MarkLogic 8.
On Linux platforms, the mlsql
utility no longer is packaged with the MarkLogic Server rpm binary. To get mlsql
on Linux now, you must install the ODBC Driver for Linux. For details on the ODBC Driver for Linux, see Configuring the ODBC Driver on Linux in the SQL Data Modeling Guide.
The tokenization rules for Cyrillic script has changed such that mixed letter and number tokens are handled consistently with Latin letter and number tokens. That is, the following now tokenizes as a single token (previously it was two tokens):
Ё1 (Cyrillic A + the digit 1)
If you have Cyrillic content in your database, you should reindex the database or reload the Cyrillic content so that it is properly tokenized and indexed in accordance with the new rules. If you do not trigger a retokenization of any existing Cyrillic content, certain queries may behave inconsistently between old content and newly loaded content.
Applications deployed with Application Builder in MarkLogic 7 and earlier will not work correctly in MarkLogic 8 until you fully re-deploy them.
If you have any applications built using Application Builder, you must remove the code from the modules database of the deployed application and then re-deploy the application. Specifically, for each Application Builder application that is upgraded from MarkLogic 7 or earlier:
The links in the navigation bar from Query Console and other tools no longer have links to Application Builder and Information Studio. To use these applications, enter the URL directly (for example, http://localhost:8000/appservices).
The following incompatible changes have been made to the Search API:
Previously, search:parse produced XML representing an annotated cts:query
that could be passed directly to search:unparse. As of MarkLogic 9, the default output from search:parse does not include annotations, so it cannot be passed to search:unparse.
You can get annotated output from search:parse in MarkLogic 9 using the $output
parameter as shown below:
search:parse("myQueryText", options, "cts:annotated-query")
The extract-metadata
query option is now deprecated. Use extract-document-data
instead. For details, see search:search or Extracting a Portion of Matching Documents in the Search Developer's Guide.
The new extract-document-data
option does not support extracting specific metadata properties, but properties are available in other ways, such as using xdmp:document-properties or by fetching all properties metadata through one of the client APIs.
The search:unparse and search:remove-constraint functions are now deprecated. If you need to deconstruct a query, modify it, and put it back together, use structured query or cts:query
with search:resolve instead.
For example, if you previously did something similar to the following:
let $ctsquery := search:parse("myQueryString", $options) (: ...modify $ctsquery... :) return search:search(search:unparse($ctsquery), $options)
Then you can achieve the same result doing the following:
let $ctsquery := search:parse("myQueryString", $options) (: ...modify $ctsquery... :) return search:resolve($ctsquery, $options)
To generate a structured query instead of a cts:query
, set the third parameter of search:parse to "search:query":
search:parse("myQueryString", $options, "search:query")
The following structured query elements have been renamed to more accurately reflect their purpose:
For details, see locks-fragment-query and properties-fragment-query in the Search Developer's Guide.
If you use the sort-order
query option to sort search results by something other than score, such as an XML element, JSON property, or field, then the database configuration must include a range index on the entity used for a sort key. Failing to create such an index causes SEARCH-BADORDERBY
to be thrown when searching. Previously, the index requirement was not enforced.
For details, see sort-order in the Search Developer's Guide.
The following built-in functions related to locks and document properties queries have been renamed to more accurately reflect their purpose.
cts:locks-query
is now cts:locks-fragment-querycts:locks-query-query
is now cts:locks-fragment-query-querycts:properties-query
is now cts:properties-fragment-querycts:properties-query-query
is now cts:properties-fragment-query-queryIn 8.0, the xdmp:uri-content-type function returns application/xml
. In 7.0, it returns text/xml
. Where MarkLogic previously returned text/xml
for an xml document, it now returns application/xml
. If you have applications that are expecting text/xml
, you will either need to change the application to accept application/xml or you will have to modify your program to send a content type of text/xml
(for example, using xdmp:set-response-content-type). MarkLogic will still accept text/xml
for xml documents (in addition to application/xml
). Similarly, JSON documents return application/json
but MarkLogic accepts either application/json
or text/json
.
As a consequence of this change, if you have a CPF application that relies on the mimetype text/xml
to identify an XML document, you must change that application to instead rely on application/xml
. In the case of a CPF application, you will have to modify your CPF pipelines and change any text/xml
mimetypes (that were referring to XML documents) to application/xml
. If you are using the default pipelines, then reinstalling CPF for the database should correct this incompatibility. Otherwise, those CPF applications will not trigger the change actions for XML documents. Similar changes are required for CPF appliations that rely on text/json
to identify JSON documents; they need the mimitype changed to application/json
.
To allow for anonymous functions in Server-Side JavaScript, the first argument of the xdmp:function built-in function takes an xs:QName?
(zero or 1 QNames) in 8.0; previously, it took an xs:QName
(exactly one QName). If you have code that does not allow for zero or 1 QNames, you will need to modify that code.
Also, if you are relying on function mapping with xdmp:function, you can no longer use function mapping with it (because it no longer takes a singleton). If you have code that function maps with xdmp:function, you will need to rewrite it to not use function mapping (by calling xdmp:function in the return of a FLOWR statement for each item in your sequence of QNames, for example).
The following incompatibilities exist between MarkLogic 8.0-5 and MarkLogic 8.0-6:
Previously, the Search API documentation stated that terms matched by the query specified in an additional-query
query option were not highlighted in search result snippets. This is no longer the case.
You should expect any terms matched by the additional-query
option to be included in highlighted sections of snippets.
There are a few incompatibilities made to the Server-Side JavaScript implementation in 8.0-3. The following are the incompatibilities:
In 8.0-4, the Server-Side JavaScript xdmp.multipartDecode function returns the headers (in the first item of the returned ValueIterator) as a JSON array; previously, it was returned as an XML element. If you have code that is expecting the XML element, you need to either rewrite your code to parse the JSON array or use the XQuery version (xdmp:multipart-decode).
In 8.0-4, there are changes to the thesaurus and spelling function modules to make them more friendly to JavaScript users. If you have JavaScript code that imports these XQuery libraries, then the following functions now return JavaScript Object by default:
For each of these function, you can set a new optional parameter to change its output. By default, these functions return XML output in XQuery and JavaScript Objects in JavaScript. If you have existing JavaScript code that uses these functions, you either need to add the new option to your code specifying the XML output or rework your code to accept the returned JavaScript Object. For details on these functions, see the API documentation for each function. In XQuery, the functions behave the same way they did in previous versions by default, but now allow you to specify the optional parameter to output JavaScript Objects instead of XML, if you so choose.
In 8.0-4, the Server-Side JavaScript API xdmp.databaseRestoreStatus
now returns an Object
; previously, it returned an Array
. The Array
that was previously returned is now the value of the "forest"
key, and there is also a "status"
key containing the current status of the restore. The xdmp.databaseBackupStatus also contains this new "status"
key, but the return type is not changed. Similarly, the XQuery counterparts to these APIs (xdmp:database-backup-status and xdmp:database-restore-status) also contain information about the status, but their signature has not changed. If you have code that relies on any of the old behavior, you will need to modify that code to work with the changed output.
In 8.0-4, the names of some error exception codes for serialization, as well as the message text, have changed as shown in the following table:
If you have code that does a try/catch looking for one of the old exceptions or the old text, or if you have tests that use the old exceptions as keys, you will have to rewrite that code to look for the new exception.
The following tools and libraries that depend on a Java Runtime Environment (JRE) now require at least Java 7, rather than Java 6:
The -aggregate_uri_id
and -delimited_uri_id
command line options are now deprecated. Use the more general -uri_id
instead.
Starting in 8.0-4, any of the REST APIs that specifies a JSON or and XML content-type
for its payload cannot have an empty payload. Previously, it allowed an empty payload. REST calls that specify a JSON or XML content-type
with an empty payload throw a MANAGE_EMPTYPAYLOAD
exception beginning in 8.0-4. For example, POST /admin/v1/init previously allowed an empty payload with a JSON or XML content, but requires the payload in 8.0-4.
If you have code that does not send a payload, then you must either add an empty JSON or XML document as the payload or change the content-type
to one that allows an empty payload (for example, text/plain
).
The following changes have been made to some of the geospatial built-in and library functions in 8.0-4:
The GML library module is now in a different namespace, and the library module no longer uses the same namespace as GML and KML data.
Module | Old Module Namespace | New Module Namespace |
---|---|---|
GML | http://www.opengis.net/gml | http://marklogic.com/geospatial/gml |
KML | http://earth.google.com/kml/2.0 | http://marklogic.com/geospatial/kml |
You must update your module import declarations in XQuery or require statements JavaScript to use the new namespace. In addition, since the module and the XML data of the same format no longer use the same namespace, you may need to change the namespace prefix you use for the module.
The following code snippets demonstrate the required changes for KML and GML in XQuery. The namespace URI in the module import declaration is changed to use the new URI, and the module namespace prefix is changed to distinguish names in the module from names in the data.
The following geospatial built-in functions are now deprecated and will be removed in a future release. You should use the corresponding built-in function with a geo prefix instead. For example, use geo:distance instead of cts:distance in XQuery, and use geo.distance instead of cts.distance in Server-Side JavaScript.
As of MarkLogic 8.0-4, the default KML data version is 2.2 and the default GML data version is 3.2. Older versions are deprecated. You should convert your data.
To continue querying older versions of data with geokml:geospatial-query or geogml:geospatial-query, specify the namespace URI of the older version in your query constructor. For example:
GML Old: gml:geospatial-query($regions, $options, $weight) New: geogml:geospatial-query( $regions, $options, $weight, "http://www.opengis.net/gml") KML Old: kml:geospatial-query($regions, $options, $weight) New: geokml:geospatial-query( $regions, $options, $weight, "http://earth.google.com/kml/2.0")
There are a few incompatibilites made to the Server-Side JavaScript implementation in 8.0-3. The following are the incompatibilities:
In 8.0-3, the spell.suggestDetailed, xdmp.filesystemDirectory, and xdmp.encodingLanguageDetect functions now return results in a ValueIterator
. In 8.0-2 and earlier, they returned results in an Array
. If you have any code that expects an Array, you must rework that code to accept a ValueIterator
; for example, you can use xdmp.arrayValues to convert the ValueIterator
result into an Array
result. For details on the ValueIterator
JavaScript type, see ValueIterator in the JavaScript Reference Guide.
In 8.0-3, the xdmp.databaseRestoreStatus function now returns a JavaScript Array
. Previously, it returned an ArrayNode
. If you have any code that expects the ArrayNode
, you must rework that code to accept an Array
.
In 8.0-3, the xdmp.gssServerNegotiate function (used for kerberos GSS authentication) returns a JavaScript object. Previously, it returned an XML element.
The Node.js interfaces that open, manipulate, or pass around transaction ids now accept either a simple id (as before) or a transaction object. You obtain a transaction object rather than an id by passing true
in for the new withState
parameter of DatabaseClient.transactions.open
. For example:
// old forms: return a transaction id, for backward compatibility db.transactions.open(); db.transactions.open({timeLimit: limit, transactionName: name}); // new forms: return transaction object; preferred. db.transactions.open(true); db.transactions.open({withState: true, ...});
In a future release, the default of withState will be changed to true and the use of transaction ids will be deprecated.
If you do not modify your code to use transaction objects rather than ids, the session affinity required by multi-statement transactions is not guaranteed to be properly preserved in all cases.
For details, see Managing Transactions in the Node.js Application Developer's Guide.
The MarkLogic features and tools that rely on Hadoop no longer support CDH 4.3. Instead, use one of the newer supported versions of Hadoop.
This change affects MarkLogic Content Pump (mlcp), the MarkLogic Connector for Hadoop, and forest storage on HDFS.
When you use HDFS for forest storage, MarkLogic must be able to find a suitable Java installation and Hadoop HDFS libraries. The algorithm for where MarkLogic looks has changed substantially as of 8.0-3.
You should now make the Hadoop libraries available to your MarkLogic hosts using one of the new Hadoop HDFS client bundles. You must unpack one of these bundles under /opt
, /usr
, or /space
. For details, see HDFS Storage in the Query Performance and Tuning Guide.
MarkLogic now locates a suitable Java installation using a different algorithm. You might need to either change the path to your JDK or set JAVA_HOME in the MarkLogic startup environment. You can now make JAVA_HOME available to MarkLogic in a way that is preserved across upgrades, using /etc/marklogic.conf. For details, see HDFS Storage in the Query Performance and Tuning Guide.
There are a few incompatible changes made to the Server-Side JavaScript implementation in 8.0-2. The following are the incompatibilities:
In 8.0-2, the Server-Side JavaScript functions fn.distinctValues and fn.subsequence behave differently from 8.0-1 if you pass in an array. In 8.0-1, these functions will extract the values out of the array to make multiple inputs, one for each item in the array. In 8.0-2, these functions treat the array as a single item. Therefore, to get the same behavior in 8.0-2, you need to call xdmp.arrayValues on the array before you pass it into these functions. For example:
fn.distinctValues([1, 1, 2]); // returns 1, 2 in 8.0-1 // returns [1, 1, 2] in 8.0-2
To modify the above code in 8.0-2 to return the same answer as in 8.0-1:
fn.distinctValues(xdmp.arrayValues([1, 1, 2])); // returns 1, 2 in 8.0-2
The nature of the change is that there are fewer times when MarkLogic coerces an array into its values in 8.0-2 than there were in 8.0-1. The newer behavior is more natural to JavaScript developers.
In addition to fn.distinctValues and fn.subsequence, this applies to any JavaScript function that takes a ValueIterator
as input to a parameter, including: fn.exactlyOne, fn.head, fn.insertBefore, fn.reverse, fn.unordered, fn.empty, fn.remove, fn.reverse, fn.zeroOrOne, fn.oneOrMore, fn.deepEqual, fn.count, cts.contains, xdmp.setSessionField
, xdmp.setServerField, and others.
In 8.0-2, the vars
parameter to the Server-Side JavaScript functions xdmp.eval, xdmp.invoke, xdmp.xqueryEval, and xdmp.spawn has been simplified so it only takes a single Object. If you have any code that you used in 8.0-1 that passes the external variables (vars
parameter) as an array of Objects, as an array of stings, or as a ValueIterator, you must rewrite that code in 8.0-2 so it passes a single Object.
The query option extract-document-data
previously caused search:search and search:resolve to return a sequence consisting of the search:response
and the extracted documents. Now, this option returns the extracted documents embedded in the search:response
as search:extracted
elements.
When you use the option with the REST Client API, the /v1/search
service returns the extracted content inside the search response if the Accept header MIME type is application/xml
or application/json
. The extracted content is still returned as individual documents when the Accept header MIME type is multipart/mixed (a multi-document read).
For details, see Extracting a Portion of Matching Documents in the Search Developer's Guide.
This change affects XCC applications that set the transaction mode (Session.setTransactionMode
) or transaction time limit (Session.setTransactionTimeout
) and use XCC v8.0-2 or later with MarkLogic Server 8.0-1 or earlier.
If your XCC application meets the above conditions, you must set the property xcc.txn.compatible
to true
. If you do not do so, an exception is raised if you set the transaction time limit or set the transaction mode to a value other than Session.TransactionMode.AUTO
.
You can set this system property on the java command line with an argument of the following form:
java -Dxcc.txn.compatible=true
You can also set the property programmatically by calling System.setProperty
.
The following change affects applications that use the REST Client API, Java Client API, or Node.js Client API and that raise RESTAPI-SRVEXERR
from a server-side JavaScript extension, transform, or custom snippeter, or other custom code.
In MarkLogic Server 8.0-1, when calling fn.error to raise RESTAPI-SRVEXERR,
error detail such as the response status code and status text are passed to fn.error as an array. Starting with MarkLogic Server 8.0-2, the error details must be passed as a sequence. You can use xdmp.arrayValues to convert the array to a sequence.
For example, if you previously had an fn.error call in an extension similar to the following:
fn.error(null, 'RESTAPI-SRVEXERR', [statusCode, statusMsg, body])
Then you should now wrap the array that is the 3rd argument to fn.error in a call to xdmp.arrayValues, similar to the following:
fn.error(null, 'RESTAPI-SRVEXERR', xdmp.arrayValues([statusCode, statusMsg, body]))
The following APIs return JSON output in 8.0-2.
In 8.0-1, these APIs returned the same XML structures that their XQuery counterparts return. If you have any JavaScript code that relies on the XML structures, you will need to modify that code to use the new JSON output.
MarkLogic 9 allows you to upgrade either from MarkLogic 5, MarkLogic 6, or MarkLogic 7. If you are upgrading from 4.2, you must first upgrade to at least MarkLogic 5, and there are some known incompatibilities between 4.2 and 5.0 that are documented in the 5.0 Release Notes. If you are upgrading from MarkLogic 7, you can skip this section. For convenience, the incompatibilities between MarkLogic 6 and MarkLogic 7 are repeated here, and are as follows:
This section describes the incompatibilities between MarkLogic 7.0-3 and 7.0-2.
Hortonworks Data Platform (HDP) is no longer a supported Hadoop distribution for use with the MarkLogic Connector for Hadoop or the distributed mode of MarkLogic Content Pump (mlcp).
The REST server configuration property ContentVersionRequest is now deprecated. If you currently use com.marklogic.admin.ServerConfigurationManager.setContentVersionRequest()
and the related ServerConfiguration.Policy
type, you should modify your application to use com.marklogic.admin.ServerConfigurationManager.setUpdatePolicy()
and ServerConfigurationManager.UpdatePolicy
instead. You should also change calls to getContentVersionRequest()
into call to getUpdatePolicy()
.
The table below shows the correspondence between Policy
values and UpdatePolicy
values. The behavior is unchanged with respect to these values.
If you used Policy Value... |
Then use UpdatePolicy Value... |
---|---|
NONE |
MERGE_METADATA |
REQUIRED |
VERSION_REQUIRED |
OPTIONAL |
VERSION_OPTIONAL |
The REST instance configuration property content-versions
is now deprecated, in favor of the new update-policy
property.
If you currently set content-versions
, you should modify your application to use the update-policy
configuration property instead. For example, if you set this property using PUT /v1/config/properties
or PUT /v1/config/properties/content-versions
, then you should now use PUT /v1/config/properties
or PUT /v1/config/properties/update-policy
to set update-policy
instead.
Similarly, you should modify any code that reads the configuration properties to expect update-policy
instead of content-versions
.
The table below shows the correspondence between content-versions
values and update-policy
values. The behavior is unchanged with respect to these values.
If you used Policy Value... |
Then use UpdatePolicy Value... |
---|---|
none |
merge-metadata |
required |
version-required |
optional |
version-optional |
In previous versions, you could use the REST Client API to retrieve the internal XML representation of a JSON document using GET /v1/documents
and specifying XML in the format
request parameter or application/xml
in the Accept header.
As of MarkLogic 7.0-3, JSON documents are always returned as JSON. You can still examine the internal representation of a JSON document using XQuery or the Query Console database explorer.
In MarkLogic 7.0-3, the numeric precision of a float has increased. For example:
xs:float(3435.99884) (: Returns 3436 in 7.0-2, returns 3435.999 in 7.0-3 :)
In most cases, this will not cause an incompatibility, as it is just returning a more precise number. But if you have application logic that relies on the old behavior, you will have to make changes to account for the greater precision.
This section describes the incompatibilities between MarkLogic 7.0-1 and 7.0-2.
The JSON output from the manage REST resource addresses with the metrics
view has been changed and you may need to change any custom clients that consume this JSON data.
com.marklogic.mapreduce.MarkLogicDocument
is now an interface instead of a class. The previous functionality of MarkLogicDocument
is provided by the new class com.marklogic.mapreduce.DatabaseDocument
.
Modify your code and job configuration to use DatabaseDocument instead of MarkLogicDocument.
The HTTP client XQuery APIs (xdmp:http-delete, xdmp:http-get, xdmp:http-post, xdmp:http-put, and so on) now require a privilege. Previously, these functions did not require a privilege. To support these privileges, the following privileges are added to MarkLogic 9:
http://marklogic.com/xdmp/privileges/xdmp-http-get
http://marklogic.com/xdmp/privileges/xdmp-http-head
http://marklogic.com/xdmp/privileges/xdmp-http-options
http://marklogic.com/xdmp/privileges/xdmp-http-delete
http://marklogic.com/xdmp/privileges/xdmp-http-post
http://marklogic.com/xdmp/privileges/xdmp-http-put
Additionally, the network-access
role has been added, which contains all of these privileges.
If you have code that accesses these functions with a user that does not have the admin
role, you will have to add these privileges (or the network-access
role) to the set of privileges inherited by your users. For details on adding privileges, see Security Administration in the Administrator's Guide. For details on security, see Security Guide.
The XQuery HTTP client functions (xdmp:http-delete, xdmp:http-get, xdmp:http-post, xdmp:http-put, and so on) now fully implement HTTP 1.1, including the use of connection keep-alives and built-in decoding of chunked transfer encoded responses. In most cases, this will not cause any incompatible behavior, but if your code tried to perform some work to do HTTP 1.1 features such as taking a chunked response as a large binary and decoding the chunks in XQuery, then that code might behave differently in MarkLogic 7. If you have such code, you might need to rework it in MarkLogic 7.
The xdmp:get-request-username and xdmp:get-request-user functions have changed slightly in MarkLogic 7.
In previous releases, xdmp:get-request-username always returned the user in the Authorization
HTTP header; in MarkLogic 7, if you are using application-level authentication, then it returns the user from the last successful call to xdmp:login (when using any other authentication scheme, it is unchanged from previous releases and returns the user in the Authorization
HTTP header).
In previous releases, xdmp:get-request-user returned the ID of the current user; in MarkLogic 7, if you are using application-level authentication, then it returns the user ID from the last successful call to xdmp:login (when using any other authentication scheme, it now returns the user ID corresponding to the user in the Authorization
HTTP header). If you want the old behavior of returning the ID of the current user, use the new function xdmp:get-current-userid.
If you have any code that uses the xdmp:get-request-username or xdmp:get-request-user functions, you might need to change it to work with the current behavior.
The various loading APIs (for example, xdmp:document-load and xdmp:document-insert) have an option to specify the forest in which a document is loaded. In MarkLogic 7, those forest options are only available with the locking
parameter on the database set to strict
(the default is fast
). If you try to specify forest placement with fast
locking, it will throw an XDMP-PLACEKEYSLOCKING exception. Previously, this operation would be allowed.
In most cases, it is not recommended to specify a placekey, as MarkLogic does a good job of distributing data. If you want to continue to use the forest placekeys when loading or updating, you must change your locking
parameter to strict
or change your code to no longer use forest placekeys. You can also consider using Tiered Storage to control what data goes into which forests. For details on Tiered Storage, see Tiered Storage in the Administrator's Guide.
In MarkLogic 7, there is a change to the way custom dictionaries are stored for languages that use a unified cd (Japanese and both Simplified and Traditional Chinese). The custom dictionaries for those languages now have separate files for tokenization and for stemming. If you are using these languages and you have created a custom dictionary, you must re-save the custom dictionary in MarkLogic 7, which will save it in the new format.
For example, if you have a Japanese language custom dictionary, run the following XQuery program to re-save the custom dictionary:
import module namespace cdict="http://marklogic.com/xdmp/custom-dictionary" at "/MarkLogic/custom-dictionary.xqy"; cdict:dictionary-save("ja", cdict:dictionary-read("ja"))
In MarkLogic 7, the behavior of default attributes has changed when you are copying XML nodes that have an in-scope schema with default attributes. In MarkLogic 6, the default attributes were applied in the copied node. In MarkLogic 7, the default attributes are still applied in the data model of the copied node, but they will only be serialized if default-attributes=yes
is set in the serialization options (for example, the xdmp:output
option). This is true for copied nodes in both XQuery (for example, see below) and XSLT (for example, xsl:copy
).
The following shows an example using the XHTML schema, which is always in-scope.
xquery version "1.0-ml"; declare option xdmp:output "default-attributes=no"; (: the above xdmp:output declaration is the default :) <x>{xdmp:unquote('<html xmlns="http://www.w3.org/1999/xhtml"> <body> <p>hello</p> </body> </html> ')}</x> => In MarkLogic 7 returns: (no default attributes on html element) <x> <html xmlns="http://www.w3.org/1999/xhtml"> <body> <p>hello</p> </body> </html> </x> In MarkLogic 6 returns: (added default attribute version on html element) <x> <html version="-//W3C//DTD XHTML 1.1//EN" xmlns="http://www.w3.org/1999/xhtml"> <body> <p>hello</p> </body> </html> </x>
If the xdmp:output
option is set to default-attributes=yes
, then the attributes will continue to be serialized in MarkLogic 7. Furthermore, if the copied node is used in another schema that has different default values for the default attributes, then the resulting default value for those attributes comes from the copied node, not the new schema. This change is not likely to impact very many applications, and the new behavior is what most people would expect, but if you have code that relies on the old behavior, you will need to explicitly set the xdmp:output
option is set to default-attributes=yes
.
The serialization of path range index queries has changed to use cts:path-expression
rather than cts:path
as the element name. This affects not only stored path range index queries, but also stored Alerting queries and reverse queries. All such queries must be transformed to the new serialization and reloaded.
The following XSLT stylesheet makes the required change:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:cts="http://marklogic.com/cts" version="2.0"> <xsl:template match="cts:path"> <xsl:element name="cts:path-expression"> <xsl:copy-of select="namespace::*|@*|node()"/> </xsl:element> </xsl:template> </xsl:stylesheet>
You can apply the stylesheet to affected documents using a query similar to the following:
xquery version "1.0-ml"; for $query in fn:collection("my-stored-queries") return xdmp:node-replace($query, xdmp:xslt-eval($stylesheet, $query)
Unless otherwise noted, the following changes can affect applications using either the REST or Java Client API:
This topic applies to REST and Java Client API applications that include custom content transformations for JSON documents.
JSON documents are stored in MarkLogic Server as XML. In MarkLogic 6, content transformation functions were invoked on JSON documents after conversion from JSON to XML. In MarkLogic 7, content transformations are applied before this conversion.
If you created a content transformation for MarkLogic 6 that expects JSON input, you must modify your implementation to expect XML in the http://marklogic.com/xdmp/json/basic
namespace instead of JSON text. For details on the XML representation, see Working With JSON in Application Developer's Guide.
Transformations invoked during ingestion must similarly be modified to produce XML that conforms to the internal representation for JSON documents. Transformations invoked during document retrieval can either produce conforming XML or JSON text as when generating JSON output.
For details on the new expectations, see Expected Input and Output in REST Application Developer's Guide.
This topic applies to REST and Java Client API applications running on a REST API instance created with MarkLogic 6.0-1 or later that use resource service extensions.
REST API instances created with MarkLogic Server version 6.0-1 stored resource service extensions in the Extensions database. REST API instances created with MarkLogic Server version 6.0-2 or later install resource service extensions in the modules database associated with the instance.
When you upgrade from MarkLogic 6 to MarkLogic 7 or later, any resource service extensions stored in the Extensions database on behalf of a 6.0-1 REST API instance are automatically migrated from the Extensions database to the modules database for you.
If your resource extension has dependent libraries or other assets that you installed in the Extensions database, you should migrate them by re-installing them using the new /ext
service. For details, see Managing Dependent Libraries and Other Assets in REST Application Developer's Guide.
This topic applies to REST applications that reference document properties using the JSON representation.
When you retrieve document properties in JSON format, protected system properties such as last-modified are now enclosed in an object with the key $ml.prop
. In MarkLogic 6, such properties were immediate children of the properties
container. User-defined property naming is unchanged.
The example output below shows the change in how the last-modified property value is returned by a request of the form GET /v1/documents?uri=
your-uri&category=properties&format=json
:
MarkLogic 6 | MarkLogic 7 |
---|---|
{"properties":{ "last-modified":"value" }} |
{"properties":{ "$ml.prop":{ "last-modified":"value" } }} |
The Java example application in the package com.marklogic.client.example.batch
is now in the package com.marklogic.client.example.extension
. If your application references any classes or interfaces from this package, you must change your package imports and recompile.
This topic applies to REST and Java Client API applications that insert or update document properties using JSON and either of the following are true:
In MarkLogic 6, inserting or updating user-defined document properties using JSON stored the properties as XML elements in the namespace http://marklogic.com/json
. In MarkLogic 7, such properties are stored as elements in the namespace http://marklogic.com/xdmp/json/basic
. If you insert or update a property using JSON using MarkLogic 7, the new namespace is used.
If you convert properties in the old namespace to the new namespace, then all pre-existing and future properties will use the new namespace. If you do not perform such a conversion, then you should adapt your indexes and queries to accommodate both namespaces because pre-existing properties will be in the MarkLogic 6 namespace while new or updated properties will be in the MarkLogic 7 namespace.
After upgrading to MarkLogic 7, use one of the following solutions to adapt your content and application to this change:
Use a query similar to the one in this section to change the namespace of all properties in the old namespace. The example query uses xdmp:spawn to perform the property update in batches, thereby avoiding overly large transactions.
The procedure below assumes you have an App Server, such as a REST API instance, associated with your content database. If you are not familiar with Query Console, see Query Console User Guide.
The following procedure walks you through installing a transform query in the modules root of an App Server attached to an affected database, and then running the query to modify a specific property.
update-props.xqy
. You will changed the bolded text in the next step.xquery version "1.0-ml"; declare namespace prop = "http://marklogic.com/xdmp/property"; declare namespace old-ns = "http://marklogic.com/json"; declare default function namespace "http://www.w3.org/2005/xpath-functions"; declare option xdmp:mapping "false"; declare function local:transform( $elem as element() ) as element() { let $elem-name := if (exists($elem/self::old-ns:*)) then QName("http://marklogic.com/xdmp/json/basic", local-name($elem)) else node-name($elem) return element {$elem-name} { $elem/@*, for $child in $elem/node() return typeswitch ($child) case element() return local:transform($child) default return $child } }; let $max := 100 let $batch := subsequence( cts:search(collection(), cts:properties-query( cts:element-query(xs:QName("old-ns:my-prop"), cts:and-query(())) ) ), 1, $max )/document-uri(.) return if (empty($batch)) then () else ( for $doc-uri in $batch let $current-props := xdmp:document-properties($doc-uri) / prop:properties/(* except prop:last-modified) let $modified-props := $current-props/local:transform(.) return xdmp:document-set-properties($doc-uri, $modified-props), if (count($batch) lt $max) then () else xdmp:spawn("/some/path/update-props.xqy") )
xquery version "1.0-ml"; xdmp:document-load( "/filesystem/path/update-props.xqy", <options xmlns="xdmp:document-load"> <uri>/some/path/update-props.xqy</uri> </options> )
xquery version "1.0-ml"; xdmp:invoke("/my.domain/update-props.xqy")
You must also modify any range indexes, queries, or query options for this property that depend on the old namespace. Change occurrences of http://marklogic.com/json
to http://marklogic.com/xdmp/json/basic
.
For example, if in MarkLogic 6 you defined an element range index over the property my-property
in the namespace http://marklogic.com/json
, modify the your index configuration to use the namespace URI http://marklogic.com/xdmp/json/basic
.
Similarly, if you have queries or constraint definitions using the old namespace, change them to use the new namespace. The table below contains an example of how to modify a properties constraint to use the new namespace:
You can modify your queries and query options to accommodate both namespaces. For example, if your query options already include a constraint on the old namespace, add a constraint for the new namespace, and then use an OR query to apply both constraints.
The following example uses a JSON structured or-query to demonstrate this technique. It assumes the existence of an element range index on the property in the new namespace.
{"search": { "options": { "constraint": [ { "name": "old-prop", "range": { "type": "xs:string", "element": { "name": "my-property", "ns": "http://marklogic.com/json" }, "fragment-scope": "properties" } }, { "name": "new-prop", "range": { "type": "xs:string", "element": { "name": "my-property", "ns": "http://marklogic.com/xdmp/json/basic" }, "fragment-scope": "properties" } } ] }, "query" : { "or-query" : { "queries" : [ {"range-constraint-query": { "constraint-name": "old-prop", "value": "the value" }}, {"range-constraint-query": { "constraint-name": "new-prop", "value": "the value" }} ]} } }}
Use this procedure to replace an existing element range index over the property in the old namespace with a field range index that covers both namespaces, and then modify your code and queries to the use new index. To learn more about fields, see Fields Database Settings in Administrator's Guide.
http://marklogic.com/json
and http://marklogic.com/xdmp/json/basic
. For details, see Steps 1-8 of Defining Path Range Indexes in Administrator's Guide.old-ns:my-property
and new-ns:my-property
. For details, see Configuring a New Path or Root Field in Administrator's Guide.MarkLogic Content Pump (mlcp) version 1.1 includes the following changes that potentially affect compatibility for users of mlcp version 1.0-*.
The following change might affect you if you use mlcp to load documents from compressed files (-input_compressed
). Documents created with mlcp v1.0 used the following default URI template:
/path/inside/zip/filename
Starting with version 1.1, the default URI template is:
/compressed-file-path/
path/
inside/zip/filename
This change can affect the -output_uri_replace
patterns needed to create documents with the same URIs as those created with mlcp 1.0.
For details, see Default Document URI Construction in the mlcp User Guide.
The default content character encoding when importing and exporting documents with mlcp has changed to UTF-8. Previously, mlcp used the platform default encoding for the host which mlcp was running.
You can get the previous behavior by using the following option setting:
-content-encoding system
The REST Management API version has been incremented to v2. The v1 services are no longer available. If you send a request using a v1 URL, MarkLogic Server responds with status code 410 (Gone) and a MANAGE-UNSUPPORTEDVERSION
error.
Requests that use LATEST
as the version when constructing requests will continue to work. However, you may need to make other changes due to the behavior changes between v1 and v2.
The incompatibilities between v1 and v2 are detailed in the remainder of this section
In previous releases, there were two ways to access some views: by path step or using the view
request parameter. In MarkLogic 7, the path step form of URL has been removed. You must now use the view
parameter. For example, MarkLogic 6 supported the following two ways of requesting database status, where version is v1
or LATEST
:
GET /manage/version/databases/{id|name}/status GET /manage/version/databases/{id|name}?view=status
In MarkLogic 7, only the second form is supported, as shown in the example below, where version is v2
or LATEST
.
GET /manage/version/databases/{id|name}?view=status
This change applies to the config
, counts
, edit
, and status
views for clusters, databases, forests, groups, hosts, and servers. The table below lists the affected GET methods and the equivalent MarkLogic 7 URL.
JSON output for the various GET methods now includes units for metrics that were previously flat key-value pairs. The following template summarizes the difference:
For example, in MarkLogic 6, elapsed-time
was reported as follows:
"elapsed-time" : "0.023453"
In MarkLogic 7, this field include a unit, as shown in this example:
"elapsed-time" : { "units" : "sec", "value" : "0.023453" }
The following XML element/JSON key name changes have been made:
load-detail
and rate-detail
sections of the status views for clusters, databases, forests, groups, and hosts.on-disk-size
element/key of the databases status view has been renamed to data-size
. This change affects GET /manage/version/databases/
{id|name}?view=status
output.For example, in earlier releases, the load-detail
section of the report returned by GET /manage/LATEST/hosts/{id|name}?view=status
includes a total-query-read-load
element/key. The equivalent data is now named query-read-load
.
There have been some changes to the Management API plugins for MarkLogic 9, so if you have a plugin written against previous versions, depending upon the plugin, you might need to update it.
In previous releases (MarkLogic 5 and MarkLogic 6), plugins are installed in the following folder:
Assets/plugins/marklogic/manage/v1
Plugins installed to this directory will continue to work with the following exceptions:
LATEST
(from v1
). For example, /manage/LATEST/myplugin
. No changes are required to the plugin code.For details on extending the Management API with plugins, see Extending Management API with Plugins in the Monitoring MarkLogic Guide.
The Packaging REST API has changed for MarkLogic 7. Applications written using the MarkLogic 6 Packaging REST API (v1) must be rewritten to work with the MarkLogic 7 Packaging REST API (v2).
The differences between the v1 and v2 versions of the Packaging REST API are summarized in the table below.
The Configuration Manager Packaging feature has been more tightly integrated with the Configuration Manager. Rather than exporting configurations to an XML file, as in MarkLogic 6, configurations in MarkLogic 7 are now exported, as XML, to a ZIP file.
You can import a configuration saved by MarkLogic 6 into MarkLogic 7. However, you cannot import a configuration saved in MarkLogic 7 into MarkLogic 6.
In MarkLogic 7, the xdmp:plan function requires a privilege (http://marklogic.com/xdmp/privileges/xdmp-plan
). Previously, it did not require a privilege. If you have any code that calls xdmp:plan that is run by non-privileged users, you will need to add the privilege to a role that the users are granted (or to a role that they already have).
In MarkLogic 7, the fn:analyze-string function returns an XML node in the http://www.w3.org/2005/xpath-functions
namespace, which is the namespace specified by the working draft of the latest XQuery specification. Previously, this function was not fully specified and it returned XML in the http://www.w3.org/2009/xpath-functions/analyze-string
namespace. If you have code that is expecting output in the old namespace, you will need to change that code to expect the new namepsace.