Search code examples
arangodbaql

invalid argument type in call to function 'ATTRIBUTES()' in ArangoDB


I have stored my Data in the give formate in AreangoDB, My collection name in DSP:

 "data": {
"1":   [ {"db_name": "DSP"}, {"rel": "2"} ], 
"2":   [ {"rel_name": "DataSource"}, {"tuple": "201"}, {"tuple": "202"}, {"tuple": "203"} ],
"201": [ {"src_id": "Pos201510070"}, {"src_name": "Postgres"}, {"password": "root"}, {"host": "localhost"}, {"created_date": "20151007"}, {"user_name": "postgres"}, {"src_type": "Structured"}, {"db_name": "postgres"}, {"port": "None"} ],
"202": [ {"src_id": "pos201510060"}, {"src_name": "Postgres"},{"password": "root"}, {"host": "localhost"}, {"created_date": "20151006"}, {"user_name": "postgres"}, {"src_type": "Structured"}, {"db_name": "DSP"}, {"port": "5432"} ],
"203": [ {"src_id": "pos201510060"}, {"src_name": "Postgres"}, {"password": "root"}, {"host": "localhost"}, {"created_date": "20151006"}, {"user_name": "postgres"},{"src_type": "Structured"},{"db_name": "maindb"},{"port": "5432"} ]
}

I am executing a query with the above data in the following format:

  FOR p IN NestedDSP
  LET attributes = ATTRIBUTES(p) 
  FOR attribute IN attributes 
      LET key = ATTRIBUTES(attribute)[0] 
      LET value = attribute[key] 
      RETURN { subject: attribute, predicate: key, object: value }

When I submit my query to ArangoDB, it returns the response as:

    Warnings:

[1542], 'invalid argument type in call to function 'ATTRIBUTES()''
[1542], 'invalid argument type in call to function 'ATTRIBUTES()''
[1542], 'invalid argument type in call to function 'ATTRIBUTES()''
[1542], 'invalid argument type in call to function 'ATTRIBUTES()''

Result:

[
  {
    "subject": "data",
    "predicate": null,
    "object": null
  },
  {
    "subject": "_id",
    "predicate": null,
    "object": null
  },
  {
    "subject": "_rev",
    "predicate": null,
    "object": null
  },
  {
    "subject": "_key",
    "predicate": null,
    "object": null
  }
]

Please tell me what is the problem with this query, and why the answer is like the above..I am working in ArangoDB-2.7.3-win64.

Thanks


Solution

  • Let me demonstrate how to construct such a complex query digging deep into nested data structures. I start out taking the outer parts of the query, to have an inner result:

    FOR p IN NestedDSP
      LET attributes = ATTRIBUTES(p) 
      FOR attribute IN attributes 
          RETURN attribute
    

    which gives me:

    [ 
      "data", 
      "_rev", 
      "_key", 
      "_id" 
    ]
    

    So lets dive deeper into the next layer. I guess you're only interested in the values present underneath data key right? so we pick p.data:

    FOR p IN NestedDSP
      LET attributes = ATTRIBUTES(p.data) 
      FOR attribute IN attributes 
          RETURN attribute
    

    which then gives me the keys for your next inner array:

    [ 
      "203", 
      "202", 
      "201", 
      "2", 
      "1" 
    ]
    

    We now explore what we find attached to these nodes:

    FOR p IN NestedDSP
      LET attributes = ATTRIBUTES(p.data) 
      FOR oneAttribute IN attributes 
        LET keys = p.data[oneAttribute]
          RETURN keys
    

    Its Again an array, which we need to iterate into using a FOR loop over keys:

    [
      [ 
        { 
          "src_id" : "pos201510060" 
        }, 
        { 
          "src_name" : "Postgres" 
        }, ...
    

    We add this additional FOR-loop:

    FOR p IN NestedDSP
      LET attributes = ATTRIBUTES(p.data) 
      FOR oneAttribute IN attributes 
        LET keys = p.data[oneAttribute]
        FOR key IN keys
          RETURN key
    

    we get the inner most objects:

    [ 
      { 
        "src_id" : "pos201510060" 
      }, 
      { 
        "src_name" : "Postgres" 
      }, 
      { 
        "password" : "root" 
      }, 
    ...
    

    You wanted to use the ATTRIBUTES function, but the objects only have one member, so we can access [0]:

    FOR p IN NestedDSP
      LET attributes = ATTRIBUTES(p.data) 
      FOR oneAttribute IN attributes 
        LET keys = p.data[oneAttribute]
        FOR key IN keys
          LET keyAttributes=ATTRIBUTES(key)
            RETURN keyAttributes
    

    Which gives us the object keys, one per inner most object:

    [ 
      [ 
        "src_id" 
      ], 
      [ 
        "src_name" 
      ], 
    

    We inspect whether we now get only the object keys of the inner most structure; we pick the variable names a little more clever than above:

      FOR p IN NestedDSP
        LET attributes = ATTRIBUTES(p.data) 
        FOR oneAttribute IN attributes 
          LET pairs = p.data[oneAttribute]
          FOR onePair IN pairs
            LET pairKey=ATTRIBUTES(onePair)[0]
              RETURN pairKey
    

    YES:

    [ 
      "src_id", 
      "src_name", 
      "password", 
      "host", 
        ...
    

    So now its time to construct the results object as you wanted them:

      FOR p IN NestedDSP
        LET attributes = ATTRIBUTES(p.data) 
        FOR oneAttribute IN attributes 
          LET pairs = p.data[oneAttribute]
          FOR onePair IN pairs
            LET pairKey=ATTRIBUTES(onePair)[0]
              RETURN { subject: oneAttribute, predicate: pairKey, object: onePair[pairKey] }
    

    The subject is the number identifying the outermost item, the predicate is the object key, and the object is the value in it:

    [ 
      { 
        "subject" : "203", 
        "predicate" : "src_id", 
        "object" : "pos201510060" 
      }, 
      { 
        "subject" : "203", 
        "predicate" : "src_name", 
        "object" : "Postgres" 
      }
    

    Which is hopefully what you wanted?