MarkLogic中如何实现带.find功能的路径式JSON属性更新?
批量更新JSON属性的MarkLogic解决方案求助
我需要通过路径字符串定位JSON属性并完成更新,以此修改基础文档来预览属性变更后的效果。计划用数组存储如下结构的LineItem对象:
{ "LineItem": { "Path": "/LevelA1/LevelB1/PropertyA", "Value": 12345 } }
也支持定位数组中特定对象的路径,例如:
{ "LineItem": { "Path": "/LevelA1/LevelB2/.[PropertyC3=\"ValueD3\"]/PropertyD4", "Value": 12345 } }
但我无法通过MarkLogic的.xpath功能更新该路径对应的值。于是尝试将文档转为JavaScript对象进行更新(仅需返回更新后的对象,无需写入数据库),并编写了如下setDepth函数处理点分隔的路径字符串:
function setDepth(obj, path, value) { var tags = path.split("."), len = tags.length - 1; for (var i = 0; i < len; i++) { obj = obj[tags[i]]; } obj[tags[len]] = value; }
但该函数无法处理需用.find定位数组元素的场景。我可以通过updatedDoc.LevelA1.LevelB2.find(x => x["PropertyC3"] === "ValueD3").PropertyD4或copiedObject["LevelA1"]["LevelB2"].find(x => x["PropertyC3"] === "ValueD3")["PropertyD4"]实现定位,但无法将带.find的路径字符串(如'LevelA1.LevelB2.find(x => x["PropertyC3"] === "ValueD3").PropertyD4')传入setDepth函数。
现寻求以下解决方案:
- 在MarkLogic的Server-Side JavaScript(SJS)中,如何用
.xpath更新内存中的对象; - 如何用括号语法实现
.find的功能; - 是否有更优方案批量处理含数组的层级JSON属性更新(遍历处理包含属性定位信息的数组)。
示例文档
{ "envelope": { "headers": { "sources": [ { "name": "MadeUp" } ] }, "triples": [], "instance": { "Root": { "PropertyA1": { "PropertyB1": 1, "PropertyB2": 2 }, "PropertyA2": [ { "PropertyB3": 3, "PropertyB4": 4, "PropertyB5": 5, "PropertyB6": "ValueB1", "PropertyA3": [ { "PropertyC1": { "PropertyD1": 6, "PropertyD2": "ValueD1" } } ] } ] } } } }
对应点语法与XPath路径示例
{ "LineItems": [ { "LineItem": { "Path": "envelope.instance.Root.PropertyA1.PropertyB1", "Xpath": "/envelope/instance/Root/PropertyA1/PropertyB1" } }, { "LineItem": { "Path": "envelope.instance.Root.PropertyA1.PropertyB2", "Xpath": "/envelope/instance/Root/PropertyA1/PropertyB2" } }, { "LineItem": { "Path": "envelope.instance.Root.PropertyA2.find(x => x.PropertyB6 === 'ValueB1').PropertyB3", "Xpath": "/envelope/instance/Root/PropertyA2/.[PropertyB6='ValueB1']/PropertyB3" } }, { "LineItem": { "Path": "envelope.instance.Root.PropertyA2.find(x => x.PropertyB6 === 'ValueB1').PropertyB4", "Xpath": "/envelope/instance/Root/PropertyA2/.[PropertyB6='ValueB1']/PropertyB4" } }, { "LineItem": { "Path": "envelope.instance.Root.PropertyA2.find(x => x.PropertyB6 === 'ValueB1').PropertyB5", "Xpath": "/envelope/instance/Root/PropertyA2/.[PropertyB6='ValueB1']/PropertyB5" } }, { "LineItem": { "Path": "envelope.instance.Root.PropertyA2.find(x => x.PropertyB6 === 'ValueB1').PropertyA3.find(x => x.PropertyC1.PropertyD2 === 'ValueD1').PropertyC1.PropertyD1", "Xpath": "/envelope/instance/Root/PropertyA2/.[PropertyB6='ValueB1']/PropertyA3/PropertyC1[PropertyD2='ValueD1']/PropertyD1" } } ] }
同时想问:是否可以处理带.find的点路径字符串,或者实现类似lodash.set的功能。
内容的提问来源于stack exchange,提问作者David Steiner
相关产品推荐
相关产品推荐

