【问题标题】:Query nested arrays in ArangoDB在 ArangoDB 中查询嵌套数组
【发布时间】:2016-05-04 13:46:01
【问题描述】:

我正在寻找一种在 ArangoDB 中查询嵌套数组的方法。

我的 JSON 结构是:

{
  "uid": "bykwwla4prqi",
  "category": "party",
  "notBefore": "2016-04-19T08:43:35.388+01:00",
  "notAfter": "9999-12-31T23:59:59.999+01:00",
  "version": 1.0,
  "aspects": [
    "participant"
  ],
  "description": [
    { "value": "User Homer Simpson, main actor in 'The Simpsons'", "lang": "en"}
  ],
  "properties": [
    {
      "property": [
        "urn:project:domain:attribute:surname"
      ],
      "values": [
        "Simpson"
      ]
    },
    {
      "property": [
        "urn:project:domain:attribute:givennames"
      ],
      "values": [
        "Homer",
        "Jay"
      ]
    }
  ]
}

我尝试使用如下查询来查找具有给定名称“Jay”的所有各方:

FOR r IN resource
FILTER "urn:project:domain:attribute:givennames" IN r.properties[*].targets[*]
   AND "Jay" IN r.properties[*].values[*]
RETURN r

但不幸的是它不起作用 - 它返回一个空数组。如果我对属性数组使用“1”而不是“*”,它就可以工作。但是属性数组没有固定的结构。

有人知道如何解决这个问题吗?

非常感谢!

【问题讨论】:

    标签: arrays json nested arangodb


    【解决方案1】:

    您可以使用一个简单的技巧检查过滤器的作用:您 RETURN 实际过滤条件:

    db._query(`FOR r IN resource  RETURN r.properties[*].property[*]`).toArray()
    [ 
      [ 
        [ 
          "urn:project:domain:attribute:surname" 
        ], 
        [ 
          "urn:project:domain:attribute:givennames" 
        ] 
      ] 
    ]
    

    这很清楚发生了什么。 IN 运算符只能处理一维数组。您可以通过使用FLATTEN() 删除子层来解决此问题:

    db._query(`FOR r IN resource  RETURN FLATTEN(r.properties[*].property[*])`).toArray()
    [ 
      [ 
        "urn:project:domain:attribute:surname", 
        "urn:project:domain:attribute:givennames" 
      ] 
    ]
    

    但是,虽然您的文档是有效的 json(我猜它是从 xml 转换而来的?),但您应该像在 json 中那样改变结构:

    "properties" : {
      "urn:project:domain:attribute:surname":[
          "Simpson"
      ],
      "urn:project:domain:attribute:givennames": [
          "Homer",
          "Jay"
      ]
    }
    

    由于您指定的FILTER 组合还可以找到任何其他Jay(不仅是在givennames 中找到的那些),并且FLATTEN() 的使用将禁止在您的过滤器语句中使用索引。出于性能原因,您不想使用无法在合理大小的集合上使用索引的查询。

    相比之下,您可以将givennames 上的数组索引与上述文档布局一起使用:

    db.resource.ensureIndex({type: "hash",
                            fields:
          ["properties.urn:project:domain:attribute:givennames[*]"]
        })
    

    现在仔细检查查询的解释:

    db._explain("FOR r IN resource FILTER 'Jay' IN " + 
                "r.properties.`urn:project:domain:attribute:givennames` RETURN r")
    ...
      6   IndexNode            1     - FOR r IN resource   /* hash index scan */
    ...
    Indexes used:
    By   Type   Collection   Unique   Sparse   Selectivity   Fields           Ranges
      6   hash   resource     false    false       100.00 % \
           [ `properties.urn:project:domain:attribute:givennames[*]` ] \
           ("Jay" in r.`properties`.`urn:project:domain:attribute:givennames`)
    

    它使用索引。

    【讨论】:

    • 我一直在寻找 AQL 以返回基于类似条件的文档,例如 'Jay' in array 这有帮助,尽管我不必 FLATTEN 我的结果集
    猜你喜欢
    • 2021-09-11
    • 2011-07-12
    • 2018-06-13
    • 1970-01-01
    • 2021-12-11
    • 2013-06-22
    • 1970-01-01
    • 2015-08-13
    相关资源
    最近更新 更多