我正在尝试考虑一种将字符串存储在变量中的方法,以便将该字符串用作 JSON 属性的“路径”,以便我可以更新该属性。
我的想法是,我有一个基础文档,有人想修改它,以查看更改某些属性后该文档的外观。
所以,我的想法是我可以存储一个包含如下所示对象的数组:
{
"LineItem": {
"Path": "/LevelA1/LevelB1/PropertyA",
"Value": 12345
}
我什至可以“路径”到数组中的特定对象,如下所示:
{
"LineItem": {
"Path": "/LevelA1/LevelB2/.[PropertyC3=\"ValueD3\"]/PropertyD4",
"Value": 12345
}
}
但是,我不知道如何获取 MarkLogic 中的
.xpath
功能以允许我更新该路径上的值。
因此,我试图从我的文档中创建一个对象并更新该对象(因为我真正要做的就是在服务中返回更新后的对象,我并没有真正将其写入数据库)。
我的想法是使用点表示法字符串,并使用如下函数迭代在点处分隔它的字符串:
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
时。
所以,如果有人知道:
find
功能
或我将不胜感激...
MarkLogic 使用的一种方法是利用
xdmp.nodeReplace()
。是的,这确实“写入”了一个临时文档,并且有一个事务。然而,了解 MarkLogic 的内部结构后,所讨论的结构位于内存中。这种方法的好处是,doc.nodeReplace()
的路径与 node.xpath()
的路径完全相同
我们让 Mark Logic 承担繁重的工作并隔离需要更改的内容。
方法:
写入临时文档(在内存架中)
更改临时文档(使用 xPath)
阅读更改的文档
删除文档
var doc = {
foo:123,
bar:{
baz:[
1,2,{buz:12}
]
}
}
const tempUri = "temp-" + sem.uuidString()
const path = "/bar/baz[3]/buz"
//insert
xdmp.invokeFunction(function(){
declareUpdate();
xdmp.documentInsert(tempUri, doc);
})
//update via xPath
xdmp.invokeFunction(function(){
declareUpdate();
var n = new NodeBuilder();
newBuz = n.addNumber(19).toNode();
xdmp.nodeReplace(cts.doc(tempUri).xpath(path), newBuz);
})
//read again
var newDoc = xdmp.invokeFunction(function(){
return cts.doc(tempUri)
}).toObject()
xdmp.invokeFunction(function(){
declareUpdate();
return xdmp.documentDelete(tempUri)
}).toObject()
newDoc
原文:(buz=12)
{
"foo": 123,
"bar": {
"baz": [
1,
2,
{"buz": 12}
]
}
}
结果:(嗡嗡声是19)
{
"foo": 123,
"bar": {
"baz": [
1,
2,
{"buz": 19}
]
}
}
你能在记忆中完成这一切吗? 是的 - 使用递归并使用 node.path() 测试每个节点。然而,每个节点更大的文档和递归/测试可能会消耗更多的时间和资源。上面的好处是 MarkLogic 通用索引的一部分是所有值的路径都已经被索引了。