我一直在尝试为Neo4j的查询语言Cypher找到一个查询生成器,最好使用流利的API。我没有找到太多,并决定自己花一些时间来构建一个。
到目前为止,结果是Cypher 1.9规范的流畅API查询生成器。
我想在发布代码之前使用StackOverflow开始讨论并了解想法。
这是一个演示查询,您希望使用Cypher将其发送给Neo4j。
告诉我约翰认识的所有在谷歌认识软件工程师的人(谷歌公司代码假设为12345)。约翰和把他和谷歌员工联系起来的人之间的关系强度至少应该是3(假设范围从1-5)。返回约翰的所有关系和他们在谷歌认识的人,包括这些人之间的关系。按约翰的关系名称升序排序结果,然后按关系强度降序排序。
使用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
我同意你应该着眼于Cypher 2.0来构建这个。从2.0开始,WHERE
子句与正确的START
、(可选)MATCH
和与
子句匹配非常重要,这使得流利API的设计更具挑战性。
我喜欢您的第一个示例,您只需使用文本来描述查询。说实话,第二个选项在我看来并不比构建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。