【问题标题】:Graph - show friends of friends (and 1st degree common friend)图表 - 显示朋友的朋友(以及 1 级普通朋友)
【发布时间】:2017-05-06 18:52:26
【问题描述】:

我找到了一个“朋友的朋友”遍历查询,可以满足我获取朋友的朋友的基本需求(friends of friend Query in ArangoDB 3.0)。我对其稍作修改,使其与文档中的“Knows_Graph”示例一起使用,并且我添加了一些额外的人员 (https://docs.arangodb.com/3.1/Manual/Graphs/)

我的查询使用 Dave 作为起点,并通过 Bob 和 Lucy 查找他的二年级朋友。该脚本工作正常,但我也希望它在查询结果中包含 1 级朋友(鲍勃和露西)。我可以通过将最小深度设置为 1 来做到这一点,但是如果我这样做,我不会区分 Bob 和 Lucy 的深度(参见 json 输出),所以我将无法在更大的图表上判断谁是 1 度和谁是二级

最小深度为 2 的示例代码

LET person = DOCUMENT("persons/@persons/dave")
LET foaf = (
  FOR v IN 2..2 ANY person knows      
    RETURN v
)
RETURN MERGE(person, { foaf } )

示例使用“knows”边集合和“person”集合

如果我的最小深度为 1,最大深度为 2,那么这里是 json 输出。如您所见,bob 和 lucy 显示在与其他人相同的集合级别上。我想找到一种方法以某种方式将它们显示为第一级,而不会使查询过于复杂或导致性能问题。

[
  {
    "_id": "persons/dave",
    "_key": "dave",
    "_rev": "_U7wRsJG--_",
    "name": "Dave",
    "foaf": [
      {
        "_key": "lucy",
        "_id": "persons/lucy",
        "_rev": "_U8--wPq---",
        "name": "Lucy"
      },
      {
        "_key": "henry",
        "_id": "persons/henry",
        "_rev": "_U8-_FNa---",
        "name": "Henry"
      },
      {
        "_key": "bob",
        "_id": "persons/bob",
        "_rev": "_U7wRsJC--_",
        "name": "Bob"
      },
      {
        "_key": "charlie",
        "_id": "persons/charlie",
        "_rev": "_U7wRsJG---",
        "name": "Charlie"
      },
      {
        "_key": "alice",
        "_id": "persons/alice",
        "_rev": "_U7wRsJC---",
        "name": "Alice"
      },
      {
        "_key": "eve",
        "_id": "persons/eve",
        "_rev": "_U7wRsJG--A",
        "name": "Eve"
      }
    ]
  }
]

【问题讨论】:

    标签: graph social-networking arangodb


    【解决方案1】:

    通过以下查询,您可以获得每个朋友的深度信息。

    LET person = DOCUMENT("persons/@persons/dave")
    LET foaf = (
      FOR v, e, p IN 1..2 ANY person knows      
        RETURN {v, depth: LENGTH(p.edges)}
    )
    RETURN MERGE(person, { foaf } )
    

    输出应如下所示:

    [
      {
        "_id": "persons/dave",
        "_key": "dave",
        "_rev": "_U8e0Ube---",
        "foaf": [
          {
            "v": {
              "_key": "lucy",
              "_id": "persons/lucy",
              "_rev": "_U8e0Y2u---"
            },
            "depth": 1
          },
          {
            "v": {
              "_key": "bob",
              "_id": "persons/bob",
              "_rev": "_U8ezwCm---"
            },
            "depth": 1
          },
          {
            "v": {
              "_key": "charlie",
              "_id": "persons/charlie",
              "_rev": "_U8e0-Oe---"
            },
            "depth": 2
          },
          {
            "v": {
              "_key": "eve",
              "_id": "persons/eve",
              "_rev": "_U8e0loy---"
            },
            "depth": 2
          },
          {
            "v": {
              "_key": "alice",
              "_id": "persons/alice",
              "_rev": "_U8e0ptu---"
            },
            "depth": 2
          }
        ]
      }
    ]
    

    如果您想将各个深度的朋友分组在一起,您的查询可能如下所示:

    LET person = DOCUMENT("persons/@persons/dave")
    LET foaf = (
      FOR v, e, p IN 1..2 ANY person knows      
        COLLECT depth = LENGTH(p.edges) INTO s KEEP v
        RETURN {depth, foaf: s[*].v}
    )
    RETURN MERGE(person, { foaf } )
    

    输出应如下所示:

    [
      {
        "_id": "persons/dave",
        "_key": "dave",
        "_rev": "_U8e0Ube---",
        "foaf": [
          {
            "depth": 1,
            "foaf": [
              {
                "_key": "lucy",
                "_id": "persons/lucy",
                "_rev": "_U8e0Y2u---"
              },
              {
                "_key": "bob",
                "_id": "persons/bob",
                "_rev": "_U8ezwCm---"
              }
            ]
          },
          {
            "depth": 2,
            "foaf": [
              {
                "_key": "charlie",
                "_id": "persons/charlie",
                "_rev": "_U8e0-Oe---"
              },
              {
                "_key": "eve",
                "_id": "persons/eve",
                "_rev": "_U8e0loy---"
              },
              {
                "_key": "alice",
                "_id": "persons/alice",
                "_rev": "_U8e0ptu---"
              }
            ]
          }
        ]
      }
    ]
    

    更新

    如果您需要有关人与人之间关系的更多信息,您可以返回路径而不是顶点。路径 (p) 包括所有访问的边(知道关系)和所有顶点(人)。 有关 AQL 遍历语法的更多信息:请参阅docs

    LET person = DOCUMENT("persons/@persons/dave")
    LET foaf = (
      FOR v, e, p IN 1..2 ANY person knows      
        COLLECT depth = LENGTH(p.edges) INTO s KEEP p
        RETURN {depth, foaf: s[*].p}
    )
    RETURN MERGE(person, { foaf } )
    

    【讨论】:

    • 感谢您的回答。不幸的是,我的图表图像最初并没有显示露西的二级朋友“亨利”。我已经更新了原始图像。我想知道两件事。通过您的查询,它向我显示了深度,这很好,但是我如何才能显示哪些朋友属于 Bob 以及哪些朋友属于 Lucy?其次,夏娃是鲍勃和露西的二级朋友。反正有没有显示这个?基本上我想显示所有 2 级朋友,但要向提出请求的用户显示他们有哪些 1 级朋友共同(有时会不止一个)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-10
    • 2015-10-21
    • 1970-01-01
    • 2013-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多