Neo4j 遍历 API 与 Cypher [英] Neo4j Traversal API vs. Cypher

查看:32
本文介绍了Neo4j 遍历 API 与 Cypher的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

When should I choose Neo4j’s traversal framework over Cypher?

例如,对于朋友的朋友查询,我将编写如下 Cypher 查询:

For example, for a friend-of-a-friend query I would write a Cypher query as follows:

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

相应的 Traversal 实现需要对 friends_at_depth_1friends_at_depth_2(或获取关系的核心 API 调用)进行两次遍历,并使用在遍历描述之外的普通 java 构造.如果我在这里错了,请纠正我.

And the corresponding Traversal implementation would require two traversals for friends_at_depth_1 and friends_at_depth_2 (or a core API call to get the relationships) and find the difference of these two sets using plain java constructs, outside of the traversal description. Correct me if I’m wrong here.

有什么想法吗?

推荐答案

关于 Cypher 与遍历 API 要记住的关键是遍历 API 是一种访问图的命令式方式,而 Cypher 是一种声明式方式访问图表.您可以在此处阅读有关该差异的更多信息,但简短的版本是在命令式访问中,您确切地告诉数据库如何获取图表.(例如,我想做一个深度优先搜索,修剪这些分支,当我遇到某些节点时停止,等等).在声明式图形查询中,您不是指定您想要什么,而是将如何获取它的所有方面都委托给 Cypher 实现.

The key thing to remember about Cypher vs. the traversal API is that the traversal API is an imperative way of accessing a graph, and Cypher is a declarative way of accessing a graph. You can read more about that difference here but the short version is that in imperative access, you're telling the database exactly how to go get the graph. (E.g. I want to do a depth first search, prune these branches, stop when I hit certain nodes, etc). In declarative graph query, you're instead specifying what you want, and you're delegating all aspects of how to get it to the Cypher implementation.

在您的查询中,我会稍微修改一下:

In your query, I'd slightly revise it:

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

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

(I added making sure that p<>fof because friend links might go back to the original person)

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

To do this in a traverser, you wouldn't need to have two traverser, just one. You'd traverse only FRIEND relationships, stop at depth 2, and accumulate a set of results.

现在,我将尝试论证您应该几乎总是使用 Cypher,并且永远不要使用遍历 API,除非您有非常特殊的情况.以下是我的理由:

Now, I'm going to attempt to argue that you should almost always use Cypher, and never use the traversal API unless you have very specific circumstances. Here are my reasons:

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

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

OK so when should you use traversal? Two key cases that I know of (others may suggest others)

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

这篇关于Neo4j 遍历 API 与 Cypher的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆