分析Neo4j路径查询

分析Neo4j路径查询,neo4j,profiling,cypher,Neo4j,Profiling,Cypher,我想知道neo4j是如何执行路径查询的。例如,我有一个如下所示的路径查询: match p=(n)-[r*1..10]->(m) where ( n.URI='http://yago-knowledge.org/resource/Jacob_T._Schwartz' OR n.URI='http://yago-knowledge.org/resource/Anna_Karina' ) AND filter(x IN r where type(x)=~'.*has

我想知道neo4j是如何执行路径查询的。例如,我有一个如下所示的路径查询:

match p=(n)-[r*1..10]->(m)
where
  (
    n.URI='http://yago-knowledge.org/resource/Jacob_T._Schwartz' OR
    n.URI='http://yago-knowledge.org/resource/Anna_Karina'
  ) AND
  filter(x IN r where type(x)=~'.*hasAcademicAdvisor.*') AND
  filter(y IN r where type(y)=~'.*isCitizenOf.*') AND
  filter(z IN r where type(z)=~'.*participatedIn.*') AND
  filter(u IN r where type(u)=~'.*happendedIn.*') AND
  filter(v IN r where type(v)=~'.*dealsWith.*')
return p, length(p) order by length(p) desc;
此查询用于查找源节点为“”或“”且具有特定关系的图形数据库中的路径

我在这个查询中使用了PROFILE命令,下面是我得到的执行计划

注意,第5行第5列的内容太长,所以我放了***而不是实际内容

实际上,***表示
(((((((((((属性(n,URI(0))={AUTOSTRING0})或属性(n,URI(0))={AUTOSTRING1})和非空(FilterFunction(r,x,RelationshipTypeFunction(x)~=/{AUTOSTRING2}/))和非空(FilterFunction(r,y,RelationshipTypeFunction(y)~=/{AUTOSTRING3}/))和非空(FilterFunction,r,z,relationtypeFunction(z)~)/{AUTOSTRING4}/))和非空(FilterFunction(r,u,RelationshipTypeFunction(u)~=/{AUTOSTRING5}/))和非空(FilterFunction(r,v,RelationshipTypeFunction(v)~=/{AUTOSTRING6}/)

对不起,格式不好


有人能帮我解释一下计划吗?提前谢谢!!!

我相信当你从文本控制台查看计划时,你会从下到上阅读它。你可以看到,它首先会找到
n
每隔一个节点
m
之间的每一条路径,长度为1-10(显然很多)。在找到所有这些路径后,它将获取这些路径并选择要与筛选器一起保留的路径

如果可以,您应该尝试将关系条件放在路径匹配上,而不是放在筛选器中,这样Neo4j可以在遍历时进行筛选,如果不匹配则停止遍历,这可以为您节省大量的DB访问。我注意到您的关系类型匹配非常松散,所以我不知道这有多困难,但如果您知道的话所有可能的关系类型,然后应按如下方式指定:

match p=(n)-[r:hasAcademicAdvisor|isCitizenOf|participatedIn|happendedIn|*1..10]->(m)
我很想知道为什么要使用正则表达式来匹配关系类型的更多信息。我知道有时候人们会为他们的关系类型(比如ID)输入动态值,根据我的经验,这通常是一种代码味道。通常你可以改为使用关系属性

另外两个注意事项:您没有使用标签,因此为了查找具有指定的
URI
属性的节点,首先需要搜索整个数据库。如果您使用标签并在
:label(URI)
上创建索引或约束,则该部分将更快

在本例中,我还将使用
中的
来匹配
URI

WHERE n.URI IN ('http://yago-knowledge.org/resource/Jacob_T._Schwartz', 'http://yago-knowledge.org/resource/Anna_Karina')
最后,您还应该能够利用正则表达式使其更简单(也许更高效):

但是,如果可能的话,这并不如将其放入你的
匹配中那样有效。

  • 使用标签,
  • 使用Neo4j 2.3.x
  • 对:资源(URI)使用约束
  • 考虑从URI值中删除URI前缀,这在数据库中是浪费,或者在导入时替换为名称空间
  • 不要使用regexp进行rel类型匹配,可以先使用合理的rel类型
  • 从你的关系类型中消除歧义
在您的查询中尝试此操作(在修复URI和rel类型之后)

有关查询计划的详细信息,请参阅Neo4j手册中的扩展文档


还考虑NeN4J浏览器的更为直观的查询计划

,非常感谢,布瑞恩。是的,我确实有理由使用正则表达式来匹配关系类型。实际上,在我的应用场景中,我想在一组节点之间找到路径,使这些路径包含所有指定的关系。但是,我不关心T的顺序。这是我唯一能够实现我的目标的方法。另外,我同意你关于添加标签和使用索引来提高性能的意见。我会试试看!FWIW,我给出的语法没有指定特定的顺序,只是路径上的所有关系都必须是指定的类型之一showever,我需要它们都是出现在最终路径中。啊,我明白你的意思,因此出现了
s。如果你将搜索空间放入
匹配中
,它仍然可能有助于减少搜索空间。另外,使用
任何
函数可能比
过滤器
更快,因为一旦找到答案,它就可以停止。但是对于你的用例,确保在您可能希望调查非托管扩展的过程中,所有关系都存在。非常感谢,Michael。我将尝试您的建议。
filter(x IN r where type(x)=~'.*(hasAcademicAdvisor|isCitizenOf|participatedIn|happendedIn|dealsWith).*') AND
match p=(n:Resource)-[:hasAcademicAdvisor|:isCitizenOf|:participatedIn|:happendedIn|:dealsWith*1..10]->(m:Resource)
where n.URI IN ['Jacob_T._Schwartz', 'Anna_Karina']
return p, length(p) 
order by length(p) desc;