4

The JSON patch specification used by MarkLogic PATCH API is remarkably similar to the JSON-Path standard (RFC 6902) but not exactly the same. For example, to add a node to the following document:

{
  "parent": {
    "child1": "c1-value",
    "child2": "c2-value"
  }
}

The MarkLogic patch:

{
  "insert": {
    "context": "/parent",
    "position": "last-child",
    "content": { "child3": "c3-value" }
  }
}

The JSON-Patch standard:

{
  "op": "add",
  "path": "/parent/child3",
  "value": "c3-value"
}

Is there a way to automatically translate JSON-Patch into MarkLogic Patch? My thought is to leverage libraries such as json-patch-gen to automatically generate JSON-Patch operations and convert them into MarkLogic Patches to update documents in MarkLogic.

Alternatively, is there a JavaScript library available to automatically generate MarkLogic patches by DIFF-ing two JavaScript objects?

Community
  • 1
  • 1
Fan Li
  • 1,057
  • 7
  • 11

1 Answers1

5

While the RFC influenced the MarkLogic patch specification, some stipulations of the RFC are a mismatch for MarkLogic.

  • JSON Pointer has different selection semantics than MarkLogic XPaths over JSON such as selecting container array nodes instead of item nodes. (Also, if I recall correctly, JSON Pointer doesn't support the XPath predicates.)

  • Where the patch operations in MarkLogic must be unrelated and applicable in any order, JSON Patch requires a sequential transformation. As noted in the RFC:

    Each operation in the sequence is applied to the target document; the resulting document becomes the target of the next operation.

  • The RFC doesn't support implementing insert or replace operations in user-defined server-side code.

  • The MarkLogic patch specification must be consistent for JSON and XML.

It would be possible to transform a patch expressed in a subset of the syntax of the JSON Patch RFC into a MarkLogic patch specification that uses a subset of the MarkLogic patch capabilities.

That least-common-denominator approach, however, would add to the cost, create an opportunity for bugs, and give up some features of MarkLogic.

Unless the same patch was applied to the content in other data stores, there might not be much benefit to requiring the transformation.

Hoping that's of use,

ehennum
  • 7,295
  • 13
  • 9
  • Thanks for the insight. Is there a way to automatically generate MarkLogic patch operations, either based on DIFFing two JSON objects, or by tracking the transformation? – Fan Li Aug 15 '19 at 16:11
  • I haven't tried it, but I'm wondering if the output from this library (https://www.npmjs.com/package/difflib) might provide a useful intermediate structure for generating a patch. On the other hand, if the complete replacement is available, it can be faster and easier to overwrite the entire document. – ehennum Aug 15 '19 at 21:21
  • Regarding your statement "the patch operations in MarkLogic must be unrelated and applicable in any order" Does this imply the patch operations may be applied in any order, or even in parallel? I feel this could be very difficult to verify/guarantee, even I were to manually craft a set of only minimally convoluted patch operations. – Fan Li Aug 15 '19 at 21:32
  • The operations in a patch request may not depend on one another. The REST API patch support is implemented with the node update functions such as xdmp.nodeReplace() and has the same rules about conflicting updates. – ehennum Aug 16 '19 at 15:07