简体   繁体   中英

Fetch specific key from nested document in ArangoDB

"Alpha":
    {"ABC":
     {"DEF":
         {"2017":
             {"GHI JKL":
                 {"MNO":
                     ["ABCDEFGHIJKLMNOP"]}},
             {"TGY BUG":
                  {"MNO":
                      ["1234567891012456"]}}}}}
"Alpha1":
    {"XYZ":
        {"TUW":
           {"2014":
               {"QRS PQR":
                    {"MNO":
                       ["ZYXWUTSRQPONML"]}}}}}
"Alpha2":
    {"KJM":
       {"LKI":
           {"2005":
              {"MNO":
                 ["POLKIKJUMNHY"]}}}

"Alpha3":
    {"WWW":
       {"CCC DDD":
           {"2011":
               {"MNO":
                    {"POLKIKJUMNHY":"value"}}}}}

I have four document Alpha,Alpha1, Alpha2 and Alpha3 in ArangoDB. I want to fetch data related to key "MNO" from each of document in single query.

(cross-post from https://groups.google.com/forum/#!topic/arangodb/LshKkQMH7lg )

If I understand correctly, you want to retrieve all attribute values, with an attribute key of "MNO", at an arbitrary depth.

There is no function to flatten objects in some way, and recursion is not possible in AQL.

If it's always at the same level of nesting (if it exists), then it would be possible to hard-code.

LET doc = {
  "_id": "remove-me",

  "Alpha": {
    "ABC": {
      "DEF": {
        "2017": {
          "GHI JKL": {
            "MNO": ["ABCDEFGHIJKLMNOP"],

            "PQR": true
          },
          "TGY BUG": {
            "MNO": ["1234567891012456"],
            "WXY": 987
          }
        }
      }
    }
  }
}


FOR a1 IN ATTRIBUTES(doc, true)
  FOR a2 IN ATTRIBUTES(doc[a1], true) || []
    FOR a3 IN ATTRIBUTES(doc[a1][a2], true) || []
      FOR a4 IN ATTRIBUTES(doc[a1][a2][a3], true) || []
        FOR a5 IN ATTRIBUTES(doc[a1][a2][a3][a4], true) || []
          FOR a6 IN ATTRIBUTES(doc[a1][a2][a3][a4][a5], true) || []
            FILTER a6 == "MNO"
              RETURN doc[a1][a2][a3][a4][a5]["MNO"]
              // --or-- if you want to return an object {"MNO": value} for each match
              //RETURN KEEP(doc[a1][a2][a3][a4][a5], "MNO")

I experimented with something like the following, but was unable to make it pick the "MNO" attribute from different levels. Maybe there's a logical flaw that you can work out.

LET doc = {
  "_id": "remove-me",

  "Alpha": {
    "ABC": {
      "DEF": {
        "2017": {
          "GHI JKL": {
            "MNO": ["ABCDEFGHIJKLMNOP"],

            "PQR": true
          },
          "TGY BUG": {
            "MNO": ["1234567891012456"],
            "WXY": 987
          }
        }
      }
    },
    "DEF2": {
      "MNO": 67
    }
  },
  "Beta": {
    "MNO": "Beta MNO",
    "XXX": false,
    "YYY": null
  }
}


LET v0 = []
FOR a1 IN ATTRIBUTES(doc, true)
  LET v1 = APPEND(v0, a1 == "MNO" ? doc["MNO"] : [])
  FOR a2 IN ATTRIBUTES(doc[a1], true) || []
    LET v2 = APPEND(v1, a2 == "MNO" ? doc[a1]["MNO"] : [])
    FOR a3 IN ATTRIBUTES(doc[a1][a2], true) || []
      LET v3 = APPEND(v2, a3 == "MNO" ? doc[a1][a2]["MNO"] : [])
      FOR a4 IN ATTRIBUTES(doc[a1][a2][a3], true) || []
        LET v4 = APPEND(v3, a4 == "MNO" ? doc[a1][a2][a3]["MNO"] : [])
        FOR a5 IN ATTRIBUTES(doc[a1][a2][a3][a4], true) || []
          LET v5 = APPEND(v4, a5 == "MNO" ? doc[a1][a2][a3][a4]["MNO"] : [])
          FOR a6 IN ATTRIBUTES(doc[a1][a2][a3][a4][a5], true) || []
            LET v6 = APPEND(v5, a6 == "MNO" ? doc[a1][a2][a3][a4][a5]["MNO"] : [])
            RETURN v6

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM