ArangoDB中的社交网络查询

时间:2016-04-02 09:11:09

标签: arangodb

我的数据库有以下“架构”:

  • 用户 作者 帖子
  • 用户 喜欢 帖子

我的适度测试数据库包含:

  • 162位用户
  • 442个帖子
  • 159赞

现在,我想查询最受欢迎的用户,即在所有帖子中收集最多喜欢的用户。我提出了以下问题:

FOR u IN users
    LET nblikes = SUM(FOR post IN 1 OUTBOUND u isAuthor
        RETURN LENGTH(GRAPH_EDGES('my-graph', post, { edgeCollectionRestriction: 'likes' })))
    SORT nblikes DESC
    RETURN {
        "username": u.username,
        "nblikes": nblikes
    }

在我的2014年中期MacBookPro(2.8GHz Core i7,16GB RAM)上执行大约0.8秒。 0.8s并不可耻,但是在如此小的数据集中,考虑到AFAIK,我本来期望更好,这一切都在记忆中发生。

所以如果有一些ArangoDB专家可以查看我的查询并暗示一些潜在的性能问题,我将不胜感激。非常感谢!

1 个答案:

答案 0 :(得分:3)

有几种方法可以让这个查询运行得更快。

最能改进的是用GRAPH_EDGES的内部调用替换另一个深度为1的遍历来找到" likers"如下图所示:

FOR u IN users 
  LET nblikes = SUM(
    FOR post IN 1 OUTBOUND u isAuthor 
      RETURN LENGTH(
        /* the following traversal replaces the call to GRAPH_EDGES */
        FOR liker IN 1 INBOUND post._id likes 
          RETURN 1
      )
  )
  SORT nblikes DESC
  RETURN { 
    username: u.username, 
    nblikes: nblikes
  }

GRAPH_EDGES的内部函数调用非常昂贵,摆脱它会大大缩短查询执行时间。

另一个变体是用这样的普通连接替换(现在)两个遍历:

FOR u IN users 
  LET nblikes = SUM(
    /* the following join between users, isAuthor and likes 
       replaces the traversal & GRAPH_EDGES calls */
    FOR a IN isAuthor 
      FILTER a._from == u._id 
      FOR l IN likes 
        FILTER l._to == a._to 
        RETURN 1
  ) 
  SORT nblikes DESC
  RETURN { 
    username: u.username, 
    nblikes: nblikes
  }

两个变体应该比初始查询更快,主要是因为GRAPH_EDGES在循环中调用是昂贵的。由于它是无状态AQL函数,因此需要重复设置其上下文(就像从内循环中调用它一样)。遍历和连接解决方​​案可以在呼叫之间保持更多的上下文,因此它们更便宜"。