Neo4j - Cypher vs Gremlin 查询语言

Posted

技术标签:

【中文标题】Neo4j - Cypher vs Gremlin 查询语言【英文标题】:Neo4j - Cypher vs Gremlin query language 【发布时间】:2012-11-29 06:48:34 【问题描述】:

我开始使用 REST API 使用 Neo4j 进行开发。 我看到执行复杂查询有两种选择 - Cypher(Neo4j 的查询语言)和 Gremlin(通用图形查询/遍历语言)。

这就是我想知道的 - 是否有任何查询或操作可以使用 Gremlin 完成而无法使用 Cypher 完成?反之亦然?

Cypher 对我来说似乎比 Gremlin 清楚得多,而且总的来说,Neo4j 中的人似乎都在使用 Cypher。 但是 - 如果 Cypher 与 Gremlin 相比是有限的 - 我真的很想提前知道这一点。

【问题讨论】:

Cypher 是一种非图灵完备的声明性语言。 Gremlin 是 Neo4j Java API 的精美包装器,并且是命令式的。显然,在 gremlin 中可以做一些在 cypher 中做不到的事情。 Apache Spark 3 将包含 Cypher,它充分说明了他们对此的看法。 【参考方案1】:

对于一般查询,Cypher 就足够了,而且可能更快。 Gremlin 相对于 Cypher 的优势在于您可以进行高级遍历。在 Gremlin 中,您可以更好地定义准确的遍历模式(或您自己的算法),而在 Cypher 中,引擎会尝试自行找到最佳遍历解决方案。

我个人使用 Cypher 是因为它的简单性,而且迄今为止,我还没有遇到任何必须使用 Gremlin 的情况(使用 Gremlin graphML 导入/导出函数除外)。然而,我希望即使我需要使用 Gremlin,我也会为我在网上找到的特定查询这样做,并且再也不会回来了。

您总是可以快速(在几天内)学习 Cypher,然后继续学习(长期)通用 Gremlin。

【讨论】:

有一个新的在线教程,从neo4j.org/learn/cypher 开始,您也可以开始学习。 我的理解是 Cypher 更像 SQL,因为你告诉它你想要什么,它就会知道如何去做。使用 Gremlin,您可以发出精确的遍历命令,它必须遵守。 对我来说,Gremlin 在大多数查询中恰好比 Cypher 快得多。 截至TinkerPop 3.x,Gremlin 具有命令式和声明式两种特性。您可以编写遍历来定义此答案中所述的精确遍历模式,或者您可以使用match step 来简单地定义您正在寻找的模式,Gremlin 会解决这个问题。 始终可以选择编写 Cypher 扩展来缓解 Cypher 限制。 APOC (github.com/neo4j-contrib/neo4j-apoc-procedures) 例如提供了一个很好的扩展集合。创作一个非常简单:neo4j.com/docs/java-reference/current/extending-neo4j/…【参考方案2】:

我们必须在查询中遍历数千个节点。 Cypher 很慢。 Neo4j 团队告诉我们,直接针对 Java API 实现我们的算法将快 100-200 倍。我们这样做了,并且轻松地从中获得了 60 倍的收益。由于缺乏信心,到目前为止,我们的系统中没有单个 Cypher 查询。 Easy Cypher 查询很容易用 Java 编写,复杂的查询不会执行。问题是当您的查询中有多个条件时,Cypher 无法判断执行遍历的顺序。因此,您的密码查询可能首先会以错误的方向进入图表。 我对 Gremlin 做的不多,但我可以想象你使用 Gremlin 可以获得更多的执行控制。

【讨论】:

当您说“直接针对 Java API”时,您是指嵌入 Java 中的 Neo4j 吗? 在作为独立服务器安装的 neo4j 中使用服务器扩展。 从 2018 年开始更新 - 鉴于 neo4j 的现代版本中有大量的原生索引类型,这个答案基本上已经过时了; neo4j 已发布性能数据 “直接针对 Java API 实现我们的算法”实际上有点误导。显然,从 A 点到 B 点最快的方法是走最短路径。这需要了解额外的、具体的信息。降低水平总是会胜过机器规划师,因为你知道你可以做出机器不能做的假设。然而,Cypher 可以轻松胜过简单实现的低级算法,使用所需的知识要少得多,而且实现起来要快得多。特别是因为 Cypher 在每个 Neo4j 版本中都变得更好。 (更聪明的规划者)【参考方案3】:

Neo4j 团队在 Cypher 上的努力确实令人印象深刻,而且已经取得了长足的进步。 Neo 团队通常会推动人们走向它,随着 Cypher 的成熟,Gremlin 可能会受到较少的关注。 Cypher 是一个不错的长期选择。

也就是说——Gremlin 是一个 Groovy DSL。通过其 Neo4j REST 端点使用它可以完全、不受限制地访问底层 Neo4j Java API。它(以及同类别的其他脚本插件)在低级功率方面无法匹敌。另外,您可以运行Cypher from within the Gremlin plugin。

无论哪种方式,都有一个明智的升级路径,您可以在其中学习两者。我会选择能让你更快地启动和运行的那个。在 my projects 中,当我需要表格结果或表达模式匹配时,我通常使用 Gremlin,然后调用 Cypher(无论是否来自 Gremlin 内部)——这两者都是 Gremlin DSL 的难题。

【讨论】:

【参考方案4】:

我最初开始使用 Gremlin。但是,当时 REST 接口有点不稳定,所以我切换到了 Cypher。它对 Neo4j 有更好的支持。但是,有些类型的查询根本无法使用 Cypher,或者 Cypher 无法像使用 Gremlin 那样优化。

Gremlin 是基于 Groovy 构建的,因此您实际上可以将其用作让 Neo4j 执行“Java”代码并从服务器执行各种任务的通用方式,而无需从 REST 接口获取 HTTP 命中。其中,Gremlin 可以让你修改数据。

但是,当我只想查询数据时,我会选择 Cypher,因为它更具可读性且更易于维护。 Gremlin 是达到限制时的后备。

【讨论】:

Cypher 从 Neo4j 1.7 开始支持更新查询,请参阅 docs.neo4j.org/chunked/snapshot/cypher-query-lang.html 请注意,REST 接口将在 TinkerPop 3 中消失。用户将需要将 Gremlin 字符串发送到 Gremlin 服务器(基本上是 Rexster,重命名和改进)。【参考方案5】:

Gremlin 查询可以通过编程方式生成。 (请参阅http://docs.sqlalchemy.org/en/rel_0_7/core/tutorial.html#intro-to-generative-selects 了解我的意思。) 这对于 Cypher 来说似乎有点棘手。

【讨论】:

@MattLuongo:1,我不知道neo4django,2,它不是在所有情况下都适用(例如语言不是Python)3,如果你自己编程编写查询就不一样了或者您使用库以编程方式为您创建查询。在这方面,neo4django 可以被认为是 Cypher 和 Gremlin 的替代解决方案。 哦,当然我不指望neo4django会立即适用;这是一个例子,就像你的答案中的 SQL Alchemy 一样。但是,生成 Cypher 并不是困难。 Cypher 和 Gremlin 采用不同的方法作为查询语言,但我不认为 Cypher 更难以编程方式生成......【参考方案6】:

Cypher 仅适用于简单查询。当您开始将复杂的业务逻辑合并到您的图遍历中时,它会变得异常缓慢或完全停止工作。

Neo4J 清楚地知道 Cypher 并没有削减它,因为它们还提供了 APOC 程序,其中包括备用路径扩展器(apoc.path.expandapoc.path.subgraphAll 等)。

Gremlin 更难学习,但比 Cypher 和 APOC 更强大。您可以在 Gremlin 中实现您能想到的任何逻辑。

我真的希望 Neo4J 附带一个可切换的 Gremlin 服务器(通过阅读,这曾经是这种情况)。你可以让 Gremlin 在一个实时的 Neo4J 实例上运行,但它需要跳过很多环节。我的希望是,既然 Neo4J 的竞争对手允许 Gremlin 作为选项,Neo4J 也会效仿。

【讨论】:

neo4j 是世界上最受欢迎的图形数据库,我认为他们还没有采用 gremlin 可能是有原因的。 由于您没有分享这些原因可能是什么,我认为您的评论没有任何价值【参考方案7】:

Cypher 是一种用于查询图形数据库的声明式查询语言。声明式这个术语很重要,因为它是一种不同于命令式编程范式的编程方式。

在像 Cypher 和 SQL 这样的声明式查询语言中,我们告诉底层引擎我们想要获取哪些数据,并且我们不指定我们希望如何获取数据。

在 Cypher 中,用户在 MATCH 子句中定义了一个感兴趣的子图。然后底层引擎运行模式匹配算法,在图数据库中搜索相似出现的子图。

Gremlin 兼具声明性和命令性功能。它是一种图遍历语言,用户必须明确说明如何导航图。

在这种情况下,这些语言之间的区别在于,在 Cypher 中,我们可以使用 Kleene 星号运算符来查找图形数据库中任意两个给定节点之间的路径。然而,在 Gremlin 中,我们必须明确定义所有此类路径。但是我们可以在 Gremlin 中使用重复运算符来查找图形数据库中此类显式路径的多次出现。但是,在 Cypher 中不可能对显式结构进行迭代。

【讨论】:

【参考方案8】:

如果您使用 gremlin,那么它允许您迁移到不同的图形数据库, 由于大部分图数据库都支持gremlin遍历,所以选择gremlin是个好主意。

【讨论】:

【参考方案9】:

长答案短:使用 cypher 进行查询,使用 gremlin 进行遍历。您将自己看到响应时间。

【讨论】:

怎么做?

以上是关于Neo4j - Cypher vs Gremlin 查询语言的主要内容,如果未能解决你的问题,请参考以下文章

Neo4j/Cypher 测试数据请求

如何往neo4j中批量插入cypher语句

neo4j cypher 节点可以模糊匹配么

Neo4j —— Cypher 查询语言

CYPHER 语句(Neo4j)

Neo4j:如何删除与 cypher 的特定关系?