有没有办法优化这个 Gremlin 查询?

Is there a way to optimize this Gremlin query?

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

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

对于给定的一组 "matching rules",我很难编写高效的 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")

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

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

此查询的性能将取决于图形中的边度数。由于许多人共享相同的名字,因此您很可能会有大量边进入特定的 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")))

因此,性能将主要取决于边度最低的顶点。