有没有办法优化这个 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")))
因此,性能将主要取决于边度最低的顶点。
我有一个图形数据库,看起来像这样(简化)图:
每个唯一 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")))
因此,性能将主要取决于边度最低的顶点。