我正在想办法将字符串存储在变量中,以便将该字符串用作JSON属性的“路径”,以便更新该属性。
这个想法是,我有一个基本文档,有人想修改,看看文档的外观与某些属性的变化。
所以,我的想法是,我可以存储一个数组,其中包含这样的对象:
{
"LineItem": {
"Path": "/LevelA1/LevelB1/PropertyA",
"Value": 12345
}
我甚至可以“path”到数组中的特定对象,像这样:
{
"LineItem": {
"Path": "/LevelA1/LevelB2/.[PropertyC3=\"ValueD3\"]/PropertyD4",
"Value": 12345
}
}
但是,我不知道如何在MarkLogic中获得.xpath
功能,以允许我更新该路径上的值。
所以,我试图从我的文档中创建一个Object并更新Object(因为我真正要做的就是在服务中返回更新后的Object,我并没有真正将其写入数据库)。
我的想法是使用一个点符号字符串,并在字符串上用一个像这样的函数在点处分隔它:
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
更新合适的对象时,这才有效。
我还没能弄清楚是否有一种括号表示法可以提供“where”功能(也就是点表示法中的“.find”)。
我可以这样做:updatedDoc.LevelA1.LevelB2.find(x => x["PropertyC3"] === "ValueD3").PropertyD4
还有这个:copiedObject["LevelA1"]["LevelB2"].find(x => x["PropertyC3"] === "ValueD3")["PropertyD4"]
但我就是不知道是否有一个括号符号可以让我获得.find
功能。因为这破坏了setDepth
函数:'LevelA1.LevelB2.find(x => x["PropertyC3"] === "ValueD3").PropertyD4'
作为path
传递。
如果有人知道:
1.实际上,如何使用“.xpath”在MarkLogic中更新JavaScript(sjs)中的内存对象,或者
1.如何使用括号表示法实现find
功能,
1.是否有更好的方法来完成同样的事情(循环遍历一个“某物”数组,该数组处理一个大型分层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"
}
}
]
}
那么,有没有一种方法来处理JavaScript中的点符号“string”,或者有没有一个括号符号来做等效的事情(这实际上是https://youmightnotneed.com/lodash#set正在做的事情)?
1条答案
按热度按时间wwtsj6pe1#
MarkLogic使用的一种方法是利用
xdmp.nodeReplace()
。是的,这确实“写”了一个临时文档,并且有一个交易。然而,了解MarkLogic的内部,所讨论的结构是在内存中的。这种方法的优点在于,所讨论的路径对于doc.nodeReplace()
和node.xpath()
完全相同我们让Mark Logic来做繁重的工作,并隔离需要改变的内容。
方法:
Original:(buz=12)
结果:(buz为19)
上面的好处是MarkLogic的通用索引的一部分是所有值的路径已经被索引。
你能在记忆中做到这一切吗?是-使用递归和测试每个节点和它的路径。每个节点上更大的文档和递归/测试可能会消耗更多的时间和资源。