在 MarkLogic 9 中更新 JSON 个数组
Updating JSON arrays in MarkLogic 9
我不知道如何编写一些 XQuery。我在 MarkLogic 中有一个 JSON 结构,看起来像:
{
"id": "pres003A10",
"title": "A Course About Something",
"description": "This course teaches people about some things they may not know.",
"author": "A.N. Author",
"updated": "2007-01-19",
"decks": [
{
"id":"really-basic-stuff",
"exclude": ["slide3", "slide12"]
},
{
"id":"cleverer-stuff",
"exclude": []
}
]
}
exclude
数组包含幻灯片中幻灯片的标识符(演示文稿由一层或多层幻灯片组成)。我正在尝试编写一段代码,用于在该排除列表中查找幻灯片 ID,如果存在则将其删除,如果不存在则将其添加(切换)。
我可以使用以下方法获取数组节点本身:
let $exclude := doc('/presentations/presentation.json')/object-node()/decks[id = 'markup-intro']/array-node('exclude')
但我这辈子都看不到我如何更新该数组以删除或添加项目。目的是调用类似以下的函数:
local:toggle-slide($presentation) as object-node()
{
(: xdmp:node-update(...) goes here :)
};
那么,如何更新该数组?
在内存中 JSON 节点树(和 XML 树,就此而言)是不可变的。
修改树的方法是构造一棵新树,复制没有变化的节点,创建变化的父节点和祖先节点。
也就是说,有一种更简单的方法可以修改 JSON。如果你在根节点上调用 xdmp:from-json()
,你将得到一个可变的内存映射/数组结构。
然后您可以使用地图上的 map:get()
和阵列上的 [ITEM_NUMBER] 导航到阵列,并删除或插入适当的 json:array 对象的项目。
完成后,调用 xdmp:to-json()
将根映射变回节点。
希望对您有所帮助,
如果需要更新数据库中的json,可以使用xdmp:node-replace
。 node-replace 的问题在于,您必须为其提供命名节点。为此,您需要将数组节点包装在一个对象节点中,然后动态地获取对象节点内的数组节点。这是一个工作示例:
xquery version "1.0-ml";
(: insert test data :)
xdmp:document-insert("/presentations/presentation.json", xdmp:unquote('{
"id": "pres003A10",
"title": "A Course About Something",
"description": "This course teaches people about some things they may not know.",
"author": "A.N. Author",
"updated": "2007-01-19",
"decks": [
{
"id":"markup-intro",
"exclude": ["slide3", "slide12"]
},
{
"id":"cleverer-stuff",
"exclude": []
}
]
}'
))
;
(: node-replace array-node :)
let $exclude := doc('/presentations/presentation.json')/object-node()/decks[id = 'markup-intro']/array-node('exclude')
return xdmp:node-replace($exclude, object-node{
"exclude": array-node{ "other", "slides" }
}/node())
;
(: view if changed :)
doc('/presentations/presentation.json')
注意:考虑查看 MarkLogic 的 Server-side JavaScript (SJS) 支持。这样更新 JSON 似乎更自然,尤其是当您需要一次性进行多项更改时。
HTH!
我不知道如何编写一些 XQuery。我在 MarkLogic 中有一个 JSON 结构,看起来像:
{
"id": "pres003A10",
"title": "A Course About Something",
"description": "This course teaches people about some things they may not know.",
"author": "A.N. Author",
"updated": "2007-01-19",
"decks": [
{
"id":"really-basic-stuff",
"exclude": ["slide3", "slide12"]
},
{
"id":"cleverer-stuff",
"exclude": []
}
]
}
exclude
数组包含幻灯片中幻灯片的标识符(演示文稿由一层或多层幻灯片组成)。我正在尝试编写一段代码,用于在该排除列表中查找幻灯片 ID,如果存在则将其删除,如果不存在则将其添加(切换)。
我可以使用以下方法获取数组节点本身:
let $exclude := doc('/presentations/presentation.json')/object-node()/decks[id = 'markup-intro']/array-node('exclude')
但我这辈子都看不到我如何更新该数组以删除或添加项目。目的是调用类似以下的函数:
local:toggle-slide($presentation) as object-node()
{
(: xdmp:node-update(...) goes here :)
};
那么,如何更新该数组?
在内存中 JSON 节点树(和 XML 树,就此而言)是不可变的。
修改树的方法是构造一棵新树,复制没有变化的节点,创建变化的父节点和祖先节点。
也就是说,有一种更简单的方法可以修改 JSON。如果你在根节点上调用 xdmp:from-json()
,你将得到一个可变的内存映射/数组结构。
然后您可以使用地图上的 map:get()
和阵列上的 [ITEM_NUMBER] 导航到阵列,并删除或插入适当的 json:array 对象的项目。
完成后,调用 xdmp:to-json()
将根映射变回节点。
希望对您有所帮助,
如果需要更新数据库中的json,可以使用xdmp:node-replace
。 node-replace 的问题在于,您必须为其提供命名节点。为此,您需要将数组节点包装在一个对象节点中,然后动态地获取对象节点内的数组节点。这是一个工作示例:
xquery version "1.0-ml";
(: insert test data :)
xdmp:document-insert("/presentations/presentation.json", xdmp:unquote('{
"id": "pres003A10",
"title": "A Course About Something",
"description": "This course teaches people about some things they may not know.",
"author": "A.N. Author",
"updated": "2007-01-19",
"decks": [
{
"id":"markup-intro",
"exclude": ["slide3", "slide12"]
},
{
"id":"cleverer-stuff",
"exclude": []
}
]
}'
))
;
(: node-replace array-node :)
let $exclude := doc('/presentations/presentation.json')/object-node()/decks[id = 'markup-intro']/array-node('exclude')
return xdmp:node-replace($exclude, object-node{
"exclude": array-node{ "other", "slides" }
}/node())
;
(: view if changed :)
doc('/presentations/presentation.json')
注意:考虑查看 MarkLogic 的 Server-side JavaScript (SJS) 支持。这样更新 JSON 似乎更自然,尤其是当您需要一次性进行多项更改时。
HTH!