问题描述
我正在尝试在 arangodb 中编写一个更新命令,以便在具有嵌套数组的文档中插入一个 "key":"value" 属性。
{
"OuterBlock": {
"InnerBlock": {
"key1": "value1","key2": {
"key21": "value21"
},"key3": {
"key31": "value31"
},"key4": [
{
"key41": "value1","key42": {
"key421": "value421"
},"key43": [
{
"key431": "value431","key432": {
"key4321": "value4321"
}
}
]
},{
"key44": "value44","key45": {
"key451": "key451"
}
}
]
}
}
}
我需要在 key432 下再添加一个键:值对(例如:“key4322”:“value4322”)。我首先尝试使用选择查询,然后尝试使用 MERGE 命令添加此属性。
FOR t IN test
FILTER t._key=="Test"
Collect a = t.OuterBlock.InnerBlock.key4[0].key43[0].key432 into aitems
LET newa = (MERGE(a,{"key4322": "value4322"}))
RETURN newa
返回结果如下
[
{
"key4321": "value4321","key4322": "value4322"
}
]
FOR t IN test
FILTER t._key=="Test"
collect a = t.OuterBlock.InnerBlock.key4[0].key43[0] into aitems
LET newa = (MERGE(a,{key432:
(
FOR t IN test
FILTER t._key=="Test"
Collect b = t.OuterBlock.InnerBlock.key4[0].key43[0].key432 into bitems
LET newb = (MERGE(b,{"key4322": "value4322"}))
Return newb
)
}))
RETURN newa
并且输出在key432中给了我一个额外的数组块[],它在原始数据中不存在。因此它正在改变文档的格式。我怎样才能删除这个数组块。 请提出建议。
[
{
"key431": "value431","key432": **[**
{
"key4321": "value4321","key4322": "value4322"
}
**]**
}
]
解决方法
您需要逐步替换数组元素和合并对象,因为 AQL 中的变量是不可变的。在客户端扩展嵌套对象然后在服务器端替换整个文档会更容易。尽管如此,这在 AQL 中是可能的:
FOR t IN test
FILTER t._key == "test"
LET key432 = MERGE(
t.OuterBlock.InnerBlock.key4[0].key43[0].key432,{ key4322: "value4322" }
)
LET key43 = REPLACE_NTH(
t.OuterBlock.InnerBlock.key4[0].key43,MERGE(t.OuterBlock.InnerBlock.key4[0].key43[0],{ key432 })
)
LET key4 = REPLACE_NTH(t.OuterBlock.InnerBlock.key4,MERGE(t.OuterBlock.InnerBlock.key4[0],{ key43 })
)
RETURN MERGE_RECURSIVE(t,{ OuterBlock: { InnerBlock: { key4 } } })
结果:
[
{
"OuterBlock": {
"InnerBlock": {
"key1": "value1","key2": {
"key21": "value21"
},"key3": {
"key31": "value31"
},"key4": [
{
"key41": "value1","key42": {
"key421": "value421"
},"key43": [
{
"key431": "value431","key432": {
"key4321": "value4321","key4322": "value4322"
}
}
]
},{
"key44": "value44","key45": {
"key451": "key451"
}
}
]
}
}
}
]
关于额外的数组,请记住,子查询总是像顶级查询一样返回一个数组。
LET newa = (MERGE(a,{key432:
(
FOR t IN test ... // subquery
)
要仅获取子查询返回的第一个元素,您可以执行 FIRST( FOR ... )
或 ( FOR ... )[0]
。