我正在研究一个使用Neo4j作为数据库跟踪地址之间事务的Rails应用程序。当我尝试运行此查询时:
Neo4j::Session.query("MATCH (sender:Address {address: 'abc123'})-[transaction:SENT_TO]->(receiver:Address) RETURN sender, transaction, receiver").to_a
我按预期返回一个数组,但transaction
项作为CypherRelationship指针而不是其属性的结构返回,就像它对发送方和接收方地址一样:
=> [#<struct sender=#<Address uuid: nil, address: "abc123", user_tags: nil>, transaction=CypherRelationship 30, receiver=#<Address uuid: nil, address: "xyz321", user_tags: nil>>]
如果我尝试通过执行transaction.props['amount']
之类的操作获取其中一个事务属性,则会导致新的Cypher查询运行。由于我想要在每个事务上返回多个属性,以及将返回的大量事务,我希望初始查询只是将关系的属性作为数组中的结构返回。
当我在Neo4j中直接运行查询时,这是我想要的,所以我怀疑它是neo4j-core gem的一个问题(或者我对它的使用)......任何想法?
感谢您的帮助!
答案 0 :(得分:0)
Neo4j和Neo4j核心宝石提供节点和关系的对象表示,但哪个对象最终取决于应用中定义的类。返回节点或关系时,Neo4j gem会尝试根据标签或rel类型查找对其负责的模型。找到一个时,它返回该类的实例;当找不到一个时,它返回Neo4j-core提供的一个基本类的实例:CypherNode
或CypherRelationship
。
在你的情况下,你没有得到属性的结构,你得到类型为Address
的节点的结构,因为你定义了那个模型,而CypherRelationship
,所以你没有有一个为这种关系定义的模型。模型的实例具有获取和设置属性的便捷方法,但CypherNode
和CypherRelationship
的实例却没有,因此调用props
并且您将可以访问关系的属性。
您可能需要查看CypherRelationship
代码。 https://github.com/neo4jrb/neo4j-core/blob/master/lib/neo4j-server/cypher_relationship.rb是它的主要部分,但它继承自https://github.com/neo4jrb/neo4j-core/blob/master/lib/neo4j/relationship.rb,它主要是一个抽象类,但它也提供了一些其他方法。它有一个非常基本的公共界面,主要是处理关系的便捷方法。 CypherNode
非常相似:https://github.com/neo4jrb/neo4j-core/blob/master/lib/neo4j-server/cypher_node.rb。
一般来说,我的建议是使用Neo4j::ActiveRel
为您计划在Ruby中作为对象使用的任何关系定义模型。您可以在http://neo4jrb.readthedocs.io/en/v7.0.2/ActiveRel.html找到相关文档。
另外两个注释:
如果您的查询被指示返回属性而不是完整对象,您将收到Structs而不是CypherNode
/ CypherRelationship
的实例或您的模型类。
如果您使用Cypher DSL而不是传入查询,则可以使用pluck
方法并接收对象阵列而不是结构,如果您愿意的话。 return(symbols).to_a
也可以。
Neo4j::Session.current.query
.match("(sender:Address {address: {addr} })-[transaction:SENT_TO]->(receiver:Address)")
.params(addr: 'abc123')
.pluck(:sender, :transaction, :receiver)