Search code examples
arangodbaqlfoxx

ArangoDB - How to get relations between 2 collections


I have 2 vertex collections:

  • users
  • articles

and 1 edge collection:

  • userfollow (relation between user following other users)

The problem is when user follow other users and the followed users wrote some articles, how to get the articles based on the user following?


Solution

  • You can query the data with AQL's native graph traversal in Foxx using db._query().

    Sample data

    users:

    { "_key": "john-s", "gender": "m", "name": "John Smith" }
    
    { "_key": "jane.doe", "gender": "f", "name": "Jane Doe",
      "article_ids": [
        "salad-every-day",
        "great-aql-queries"
      ]
    }
    

    articles:

    {
      "_key": "great-aql-queries",
      "title": "How to write great AQL queries"
    },
    {
      "_key": "salad-every-day",
      "title": "Delicious salads for every day"
    }
    

    userfollow:

    { "_from": "users/john-s", "_to": "users/jane.doe" }
    

    Query

    Starting at follower John, we can use AQL traversal to get all users he is following. Here, there is only Jane being followed:

    FOR v IN OUTBOUND "users/john-s" userfollow
        RETURN v
    

    The document keys of the articles Jane wrote are stored in the Jane user document itself, as an array of strings (you could also model this with edges of course). We can use DOCUMENT() to fetch the articles and return them:

    FOR v IN OUTBOUND "users/john-s" userfollow
        RETURN DOCUMENT("articles", v.article_ids)
    

    We could also return who John is following (Jane), remove the article_ids attribute for each user and merge in the full article documents:

    FOR v IN OUTBOUND "users/john-s" userfollow
        RETURN MERGE(UNSET(v, "article_ids"), {
            articles: DOCUMENT("articles", v.article_ids)
        })
    

    The result looks like this:

    [
      {
        "_id": "users/jane.doe",
        "_key": "jane.doe",
        "gender": "f",
        "name": "Jane Doe",
        "articles": [
          {
            "_key": "salad-every-day",
            "_id": "articles/salad-every-day",
            "title": "Delicious salads for every day"
          },
          {
            "_key": "great-aql-queries",
            "_id": "articles/great-aql-queries",
            "title": "How to write great AQL queries"
          }
        ]
      }
    ]