ArangoDB 数组查询数组

问题描述

我正在尝试在 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"
  }
]

所以我尝试使用以下查询将此结果与第一个块“key43”合并

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]