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

查看:537
本文介绍了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. 密码查询执行器一直在不断改进(2.2版将有一个基于成本的计划程序),当然,他们为确保密码能利用所有可用索引付出了很多努力.对于许多查询,除非您非常仔细地对遍历进行编码,否则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代码操作.在这种情况下,您将遍历器用作某种访问者函数",有时遍历比cypher更方便使用,这取决于在节点上运行的Java的性质.
  2. 有时您的性能要求如此之高,您需要手动遍历图,因为在遍历器中可以利用图结构的某些方面来使Cypher无法利用的运行速度更快.确实会发生这种情况,但是通常先行学习这不是一个好主意.

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

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