Neo4j Traversal API与Cypher

Jay*_*Jay 14 neo4j cypher

什么时候应该选择Neo4j的遍历框架而不是Cypher?

例如,对于朋友的朋友查询,我会写一个Cypher查询,如下所示:

MATCH (p:Person {pid:'56'})-[:FRIEND*2..2]->(fof) 
WHERE NOT (p)-[:FRIEND]->(fof) 
RETURN fof.pid
Run Code Online (Sandbox Code Playgroud)

并且相应的遍历实现将需要两次遍历friends_at_depth_1friends_at_depth_2(或核心API调用以获取关系)并使用普通java构造在遍历描述之外找到这两个集合的差异.如果我在这里错了,请纠正我.

有什么想法吗?

Fro*_*its 21

关于Cypher与遍历API的关键要点是遍历API是访问图形的必要方式,而Cypher是一种访问图形的声明方式. 你可以在这里阅读更多关于这种差异的内容,但简短的版本是在命令式访问中,你告诉数据库到底如何获得图表.(例如,我想进行深度优先搜索,修剪这些分支,当我点击某些节点时停止等).在声明图查询中,您可以指定您想要的内容,并且您将如何将其应用到Cypher实现中.

在您的查询中,我稍微修改它:

MATCH (p:Person {pid:'56'})-[:FRIEND*2..2]->(fof) 
WHERE NOT (p)-[:FRIEND]->(fof) AND
      p <> fof
RETURN fof.pid
Run Code Online (Sandbox Code Playgroud)

(我添加了确保,p<>fof因为朋友链接可能会回到原来的人)

要在遍历器中执行此操作,您不需要两个遍历器,只需一个.您只遍历FRIEND关系,在深度2处停留,并累积一组结果.

现在,我将试图争论你应该几乎总是使用Cypher,并且除非你有非常具体的情况,否则永远不要使用遍历API.这是我的理由:

  1. 声明性查询非常强大,因为它使您无需考虑如何进行查询.你需要知道的就是你想要的.这意味着您将更多时间专注于代码应该执行的操作,并减少实现细节的时间.
  2. 密码查询执行器一直在变得越来越好(版本2.2将有一个基于成本的计划程序),当然他们付出了很多努力来确保密码利用所有可用的索引.我可能认为,对于许多查询,cypher在查找数据方面比在遍历时做得更好,除非您在编写遍历时非常小心.
  3. Cypher只是编写代码而不是编写自己的遍历,这通常需要您实现某些类来执行专门的停止条件等.
  4. 目前,cypher可以在嵌入式数据库中运行,也可以在服务器上运行.如果要运行遍历,则无法将其远程发送到要执行的服务器; 也许充其量你可以编写一个执行遍历的服务器扩展.所以我认为cypher目前更灵活.

好的,你什么时候应该使用遍历?我知道的两个关键案例(其他人可能会建议其他案例)

  1. 有时您需要对遍历的所有内容执行复杂的自定义Java代码操作.在这种情况下,您使用遍历器作为各种"访问者函数",有时遍历比cypher更方便使用,具体取决于您在节点上运行的java的性质.
  2. 有时您的性能要求非常强烈,您需要手动遍历图形,因为您可以在遍历器中利用图形结构的某些方面使其更快,Cypher无法利用它.这确实发生了,但首先要做到这一点通常不是一个好主意.

  • PROFILE'ing Cypher还有助于弄清楚查询是否导致下面的一些浪费操作. (5认同)

Mah*_*aha 7

书中摘录

核心 API、遍历框架还是 Cypher?

核心 API 允许开发人员微调他们的查询,以便他们表现出与底层图的高度亲和力。编写良好的 Core API 查询通常比任何其他方法都快。缺点是此类查询可能很冗长,需要开发人员付出大量努力。此外,它们与底层图的高度亲和力使它们与其结构紧密耦合。当图结构发生变化时,它们通常会中断。Cypher 可以更容忍结构变化——诸如可变长度路径之类的东西有助于减轻变化和变化。

Traversal Framework 比 Core API 的耦合更松散(因为它允许开发人员声明信息目标),而且不那么冗长,因此与使用 Traversal Framework 编写的查询相比,使用 Traversal Framework 编写的查询通常需要更少的开发人员工作量。核心 API。然而,因为它是一个通用框架,所以 Traversal Framework 的性能往往比编写良好的 Core API 查询稍差。

如果我们发现自己处于使用 Core API 或 Traversal Framework 进行编码的不寻常情况(从而避开 Cypher 及其可供性),那是因为我们正在处理一种边缘情况,我们需要精心设计一个无法有效表达的算法使用Cypher 的模式匹配。在 Core API 和 Traversal Framework 之间进行选择是决定 Traversal Framework 的更高抽象/更低耦合是否足够,或者 Core API 的接近金属/更高耦合是否实际上是实现一个必要的问题算法正确并符合我们的性能要求。

参考:图形数据库,互联数据的新机遇,第 161 页

什么是密码?

开发人员文档中的定义如下:cypher 是一种声明性的、受 SQL 启发的语言,用于使用 ascii-art 语法直观地描述图形中的模式。

您可以在此处找到更多相关信息。

什么是核心 API?

我发现这个页面有以下句子:

除了面向图形数据库的面向对象的 API,使用NodeRelationshipPath对象外,它还提供高度可定制、高速遍历和图形算法的实现。

所以实际上,核心 API 处理基本对象,例如NodeRelationship属于org.neo4j.graphdb包。

您可以在其开发人员指南中找到更多信息。

什么是遍历 API?

Traversal API 为核心 API 增加了更多的接口,帮助我们方便地进行遍历,而不是从头开始编写整个遍历逻辑。这些接口包含在org.neo4j.graphdb.traversal包中。

您可以在其开发人员指南中找到更多信息。

三者之间的关系

根据这个答案

Traversal API建立在Core API之上,Cypher建立在Traversal API之上;所以你可以在 Cypher 中做的任何事情,都可以用其他 2 来完成。

所有三个都完成了相同的示例

2012 年的教程展示了执行相同任务的所有三个操作,其中 Core API 速度最快。它包括安德烈斯泰勒的引述:

Cypher 才一岁多。由于我们对开发人员的限制很大,因此我们必须非常挑剔我们在第一阶段的工作重点是探索语言,了解我们的用户如何使用查询语言,并扩展功能集到一个合理的水平。
我相信 Cypher 是我们未来的 API。我知道您可以通过手写查询轻松超越 Cypher。就像有史以来创建的每种语言一样,一开始你总是可以通过手工编写比编译器做得更好,但最终,编译器赶上了

文章结论:

到目前为止,我只使用了与 neo4j 一起工作的 Java Core API,我将继续这样做。
如果您处于高速场景中(我相信每个 Web 应用程序都是一个),您应该真正考虑切换到 neo4j Java 核心 API 来编写查询。它可能不像 Cypher 或 traverser Framework 那样好看,但速度的提高是值得的。
我个人也喜欢你自己遍历核心时的控制量。