有没有一种方法可以优化此Gremlin查询?

时间:2019-11-11 12:10:14

标签: graph-databases gremlin amazon-neptune

我有一个图形数据库,看起来像这样的(简化的)图:

Graph diagram

每个唯一ID具有许多属性,这些属性表示为从ID到该属性的唯一值的边缘。基本上,这意味着如果两个ID节点具有相同的电子邮件,则它们的has_email边都将指向同一节点。在该图中,显示的两个ID共享一个名字和一个姓氏。

对于给定的一组“匹配规则”,我很难编写高效的Gremlin查询来找到匹配的ID。匹配规则将由一组属性组成,对于要视为来自同一个人的ID,这些属性必须全部相同。我目前用于根据人们的名字,姓氏和电子邮件来匹配他们的查询如下:

g.V().match(
    __.as("id").hasId("some_id"),
    __.as("id")
        .out("has_firstName")
        .in("has_firstName")
        .as("firstName"),
    __.as("id")
        .out("has_lastName")
        .in("has_lastName")
        .as("lastName"),
    __.as("id")
        .out("has_email")
        .in("has_email")
        .as("email"),
    where("firstName", eq("lastName")),
    where("firstName", eq("email")),
    where("firstName", neq("id"))
).select("firstName")

查询返回与输入some_id相匹配的ID列表。

当该查询尝试将ID与一个特别常用的名字匹配时,它变得非常非常慢。我怀疑match步骤是问题所在,但到目前为止,我一直在努力寻找一个没有运气的替代方法。

1 个答案:

答案 0 :(得分:6)

此查询的性能将取决于图形中的边缘度。由于许多人使用相同的名字,因此您很可能在特定的firstName顶点中拥有大量的优势。 您可以进行如下假设:具有相同姓氏的人少于具有相同名字的人。当然,共享相同电子邮件地址的人应该更少。有了这些知识,您就可以首先开始遍历度数最低的顶点,然后从那里进行过滤:

g.V().hasId("some_id").as("id").
  out("has_email").in("has_email").where(neq("id")).
  filter(out("has_lastName").where(__.in("has_lastName").as("id"))).
  filter(out("has_firstName").where(__.in("has_firstName").as("id")))

那样,性能将主要取决于边缘度最低的顶点。