【问题标题】:Neo4j Cypher Query BuilderNeo4j 密码查询生成器
【发布时间】:2014-03-15 23:10:18
【问题描述】:

我一直在尝试使用 Neo4j 的查询语言 Cypher 的查询构建器,最好使用流畅的 API。我没有找到太多东西,并决定花一些时间自己建造一个。

目前的结果是针对 Cypher 1.9 规范的流畅 API 查询构建器。

在发布代码之前,我想使用 StackOverflow 开始讨论并了解想法。

这是一个您希望使用 Cypher 发送到 Neo4j 的演示查询。

告诉我约翰认识的所有认识 Google 软件工程师的人(Google 公司代码假定为 12345)。 John 与将他与 Google 员工联系起来的人之间的关系强度至少应为 3(假设范围为 1-5)。 返回 John 的所有联系人以及他们在 Google 认识的人,包括这些人之间的关系。 按 John 的连接名称升序排列结果,然后按关系强度降序排列。

使用 Fluent-Cypher:

Cypher
    .on(Node.named("john").with(Index.named("PERSON_NAMES").match(Key.named("name").is("John"))))
    .on(Node.named("google").with(Id.is(12345)))

    .match(Connection.named("rel1").andType("KNOWS").between("john").and("middle"))
    .match(Connection.named("rel2").andType("KNOWS").between("middle").and("googleEmployee"))
    .match(Connection.withType("WORKS_AT").from("googleEmployee").to("google"))

    .where(Are.allOfTheseTrue(Column.named("rel1.STRENGTH").isGreaterThanOrEqualTo(3)
            .and(Column.named("googleEmployee.TITLE").isEqualTo("Software Engineer"))))

    .returns(Columns.named("rel1", "middle", "rel2", "googleEmployee"))
    .orderBy(Asc.column("middle.NAME"), Desc.column("rel1.STRENGTH"))

产生以下查询:

START john=node:PERSON_NAMES(name='John'),google=node(12345) MATCH john-[rel1:KNOWS]-middle,middle-[rel2:KNOWS]-googleEmployee,googleEmployee-[:WORKS_AT]->google WHERE ((rel1.STRENGTH >= '3' AND googleEmployee.TITLE = 'Software Engineer')) RETURN rel1,middle,rel2,googleEmployee ORDER BY middle.NAME ASC,rel1.STRENGTH DESC

【问题讨论】:

  • 这里有什么问题?
  • 这更像是一个开放式问题,旨在接收有关流畅密码 API 的反馈和建议。
  • 你见过(Java版)github.com/neo4j/cypher-dsl
  • 我喜欢你的 DSL,把它放在 github/maven/npm 上然后写博客怎么样?这将是收集反馈的最佳方式。 Neo4j 谷歌小组也可能更适合这类讨论。
  • dsl 与最新版本的 Neo4J 兼容

标签: neo4j cypher dsl fluent query-builder


【解决方案1】:

我同意您应该着眼于 Cypher 2.0 来构建它。从 2.0 开始,WHERE 子句与正确的 START(OPTIONAL) MATCHWITH 子句匹配非常重要,这使得流畅 API 的设计更具挑战性。

【讨论】:

    【解决方案2】:

    我喜欢您仅使用文本来描述查询的第一个示例。说实话,第二个选项在我看来并不比构建 Cypher 查询本身容易得多。该语言非常易于使用并且有据可查。添加另一层抽象只会增加复杂性。但是,如果您能找到将这种自然语言请求转换为 Cypher 请求的方法,那就太好了:)

    另外,为什么不直接开始使用 Cypher 2.0 呢?

    最后,在这里查看:http://github.com/noduslabs/infranodus – 我正在处理类似的问题,但将节点添加到数据库中,而不是查询它们。我选择使用#hashtags 让人们更容易理解他们的查询应该如何组织(因为我们已经使用它们)。因此,在您的情况下,它可能会变成类似

    @show-all #people who #John :knows who :know #software-engineers :at #Google. 
    
    @relationship-strength between #John and the #people who are @linked to #Google #software-engineers should be at least @3 
    
    @return @all of #John's @connections and the #people they :know at #Google, including the @relationships-between those #people. 
    
    @sort the @results @by-name of #John's @connections in @ascending order and then by @relationship-strength in @descending order.
    

    (假设#hashtags 指的是节点,@at 指的是对它们的操作)

    如果你能完成这样的事情,我认为这将是对已经易于使用的 Cypher 的更好和更有用的简化。

    【讨论】:

    • 嘿deemeetree 感谢您的回复。我同意,Cypher 已经很容易理解了。 Fluent API 的实际好处更多在于它读起来像文本并且很容易理解我们正在尝试做的事情,但更重要的是,该 API 只允许您将定义明确的格式放在一起,从而产生语法上正确询问。摆弄字符串操作来组合一个 Cypher 查询非常容易出错,没有人知道字符串中的内容是否正确。在这里,如果你做错了什么,编译器会报错。
    猜你喜欢
    • 2013-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多