我有一个图形数据库,看起来像这样的(简化的)图:
每个唯一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
步骤是问题所在,但到目前为止,我一直在努力寻找一个没有运气的替代方法。
答案 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")))
那样,性能将主要取决于边缘度最低的顶点。