Search code examples
node.jsarangodbarangojs

ArangoDB: Join with nested object collection keys


Need some help with ArangoDB join query. I have documents like the following, where User contains Group collection keys in nested object(groups). When I query users, I need to join the group collection and alter response. Should be done WITH QUERY only. Please check the example give below to get more clarity.

// User Collection
[
  {
    _key: "312121"
    name: "Ash",
    groups: {
      "1": ["323223", ...etc], // Group collection _keys;
      "2": ["342323", ...etc] // Group collection _keys;
    } 
  }
]

// Group Collection
[
  {
    _key: "323223"
    name: "Group 1"
  },
  {
    _key: "313131"
    name: "Group 2"
  }
]

I tried this query:

LET user = DOCUMENT('users/312121')
LET groups_keys = ATTRIBUTES(user.groups) // ["1", "2"]
LET list = (
  FOR key IN groups_keys
  LET groups = (
     FOR group_key IN user.groups[key] // user.groups["1"] and so on..
     LET group = DOCUMENT(CONCAT('groups/', group_key))
     RETURN { group_id: group._key, name: group.name }
  )
  RETURN { [key]: groups }
)

RETURN MERGE(user, { groups: groups })

Which returns the groups as Array but need the groups to be an Object

// Current Output: 
{
  _key: "312121"
  name: "Ash",
  groups: [ // <-- This should be object, not an array
    {
      "1": [{ _key: "323223", name: "Group 1" }]
    },
    {
      "2": [{ _key: "313131", name: "Group 2" }]
    }
  ]
}

But It should be in this format:

// Expected Output:

{
  _key: "312121"
  name: "Ash",
  groups: { // <-- like this
    "1": [{ _key: "323223", name: "Group 1" }],
    "2": [{ _key: "313131", name: "Group 2" }]
  }
}

Your help would be much appreciated!


Solution

  • Using MERGE

    MERGE [docs] accepts an array parameter as well:

    LET list = MERGE(
      /* omitted */
      RETURN { [key]: groups }
    )
    

    Using ZIP

    Alternative solution could also be with ZIP [docs]:

    LET list = (
      /* omitted */
      RETURN { key, groups } // Notice the format
    )
    LET obj = ZIP(list[*].key, list[*].groups)