2015-11-24 124 views
1

我想知道如何在neo4j中执行路径查询。例如,我有以下所示的路径的查询:分析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; 

此查询是找到与源节点“http://yago-knowledge.org/resource/Jacob_T._Schwartz”或“http://yago-knowledge.org/resource/Anna_Karina”具有一定的关系的曲线图数据库路径。

我对此查询使用PROFILE命令,下面是我得到的执行计划。

enter image description here

注意,在第5行第5栏的内容太长,所以我把***而不是把实际的内容。

其实,***表示((((((Property(n,URI(0)) == { AUTOSTRING0} OR Property(n,URI(0)) == { AUTOSTRING1}) AND nonEmpty(FilterFunction(r,x,RelationshipTypeFunction(x) ~= /{ AUTOSTRING2}/))) AND nonEmpty(FilterFunction(r,y,RelationshipTypeFunction(y) ~= /{ AUTOSTRING3}/))) AND nonEmpty(FilterFunction(r,z,RelationshipTypeFunction(z) ~= /{ AUTOSTRING4}/))) AND nonEmpty(FilterFunction(r,u,RelationshipTypeFunction(u) ~= /{ AUTOSTRING5}/))) AND nonEmpty(FilterFunction(r,v,RelationshipTypeFunction(v) ~= /{ AUTOSTRING6}/)))

对不起坏格式。

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

回答

1

我相信当你从文本控制台看你从底部到顶部阅读它的计划。这可以看到,它首先找到每个节点m之间的每个n之间的单个路径,长度为1-10(显然很多)。在找到所有这些路径之后,它将采取它们并选择哪些与过滤器保持一致。

如果可以,您应该尝试将关系条件放在路径匹配而不是过滤器上,以便Neo4j可以在遍历时进行过滤,并在不匹配时停止遍历,这可以为您节省大量数据库访问。我注意到,你们的关系类型匹配是相当宽松的,所以我不知道有多难,这将是,但如果你知道所有可能的关系类型,那么你应该像这样指定它们:

match p=(n)-[r:hasAcademicAdvisor|isCitizenOf|participatedIn|happendedIn|*1..10]->(m) 

我d有兴趣了解关于为什么使用正则表达式来匹配关系类型的更多信息。我知道有时候人们会为他们的关系类型(如ID)提供动态值,根据我的经验,这通常是一种代码味道。通常你可以改用关系属性。

其他一些注意事项:您没有使用标签,因此为了找到具有您指定的URI属性的节点,它首先需要搜索整个数据库。如果您使用标签并在:Label(URI)上创建索引或约束,那么该部分将快得多。

我也将使用IN匹配在这种情况下URI

WHERE n.URI IN ('http://yago-knowledge.org/resource/Jacob_T._Schwartz', 'http://yago-knowledge.org/resource/Anna_Karina') 

最后,您还应该能够利用正则表达式来使这个简单的(或许更有效):

filter(x IN r where type(x)=~'.*(hasAcademicAdvisor|isCitizenOf|participatedIn|happendedIn|dealsWith).*') AND 

但是,如果可能的话,那还不如将其放入MATCH那么有效。

+0

太感谢你了,布莱恩。是的,我有我的理由使用正则表达式来匹配关系类型。实际上,在我的应用场景中,我想要在一组节点之间找到路径,以便这些路径包含所有指定的关系。但是,我不关心关系的顺序。这是我想出能够实现我的目标的唯一途径。另外,我同意你关于添加标签和使用性能索引。我会尝试的! – sgao

+0

FWIW,我给出的语法没有指定特定的顺序,只是沿着路径的所有关系都必须是指定类型之一 –

+0

但是,我需要所有关系都出现在最终路径中。 – sgao

0
  • 使用标签,
  • 使用的Neo4j 2.3。X,
  • 使用上的限制:资源(URI)
  • 考虑您的URI值去掉URI前缀,它只是在浪费DB,或与命名空间进口
  • 不使用正则表达式替换针对Rel型匹配,你可以使用明智的REL-类型的
  • 删除不确定性开始从你们的关系类型

尝试此查询

(固定的URI和Rel-类型后)
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; 

有关查询计划的详细信息请参阅的Neo4j广泛的文档手册

还要考虑Neo4j的浏览器更加直观的查询计划

+0

非常感谢,Michael。我会尝试你的建议。 – sgao