首页 > 解决方案 > ArangoDB 数组查询数组

问题描述

我正在尝试在 arangodb 中编写一个更新命令,以在具有嵌套数组的文档中插入一个“键”:“值”属性。

{
  "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"
      }
    **]**
  }
]

标签: arangodbaql

解决方案


您需要逐步替换数组元素并合并对象,因为 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, 0,
    MERGE(t.OuterBlock.InnerBlock.key4[0].key43[0], { key432 })
  )
  LET key4 = REPLACE_NTH(t.OuterBlock.InnerBlock.key4, 0,
    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 ... )or ( FOR ... )[0]


推荐阅读