简体   繁体   English

Rails Neo4j查询返回CypherRelationship而不是关系值

[英]Rails Neo4j query returning CypherRelationship instead of relationship values

I'm working on a Rails application that tracks transactions between addresses, using Neo4j as the database. 我正在使用Neo4j作为数据库的Rails应用程序,该应用程序跟踪地址之间的事务。 When I try to run this query: 当我尝试运行此查询时:

Neo4j::Session.query("MATCH (sender:Address {address: 'abc123'})-[transaction:SENT_TO]->(receiver:Address) RETURN sender, transaction, receiver").to_a

I get back an array, as expected, but the transaction item returns as a CypherRelationship pointer rather than a struct of its properties like it does for the sender and receiver addresses: 正如预期的那样,我得到了一个数组,但是transaction项作为CypherRelationship指针返回,而不是像发送方和接收方地址那样返回其属性的结构:

=> [#<struct sender=#<Address uuid: nil, address: "abc123", user_tags: nil>, transaction=CypherRelationship 30, receiver=#<Address uuid: nil, address: "xyz321", user_tags: nil>>]

If I try to get one of the transaction properties by doing something like transaction.props['amount'] it causes a new Cypher query to run. 如果我尝试通过执行诸如transaction.props['amount']之类的操作来获取事务属性之一,则会导致运行新的Cypher查询。 Since there are multiple properties I want to get back on each transaction, and a large number of transactions that will be returned, I would like for the initial query to simply return the properties of the relationship as a struct within the array. 由于我想获得每个事务的多个属性,并且将返回大量事务,因此我希望初始查询只是将关系的属性作为数组中的结构返回。

This works how I want it to when I run the query directly in Neo4j, so I suspect it's an issue with the neo4j-core gem (or my use of it)... any ideas? 当我直接在Neo4j中运行查询时,这可以达到我想要的效果,所以我怀疑这是neo4j-core gem(或我的使用)的问题……有什么想法吗?

Thanks for your help! 谢谢你的帮助!

The Neo4j and Neo4j-core gems provide object representations of nodes and relationships, but which object you'll wind up with depends entirely on the classes defined within your app. Neo4j和Neo4j核心gem提供了节点和关系的对象表示,但是最终要使用的对象完全取决于应用程序中定义的类。 When a node or relationship is returned, the Neo4j gem attempts to locate a model that is responsible for it based on labels or rel type. 当返回节点或关系时,Neo4j gem会尝试根据标签或rel类型来定位对此负责的模型。 When one is found, it returns an instance of that class; 找到一个时,它返回该类的一个实例。 when one is not found, it returns an instance of one of the basic classes provided by Neo4j-core: CypherNode or CypherRelationship . 如果找不到一个,它将返回Neo4j-core提供的基本类之一的实例: CypherNodeCypherRelationship

In your case, you're not getting structs of properties, you're getting structs of nodes of type Address , since you have that model defined, and CypherRelationship , so you don't have a model defined for that type of relationship. 在您的情况下,您没有得到属性的结构,而是得到了Address类型的节点的结构,因为您定义了该模型,而CypherRelationship则没有为该类型的关系定义模型。 Instances of your models have convenience methods for getting and setting properties but instances of CypherNode and CypherRelationship do not, so call props and you'll have access to the relationship's properties. 您的模型实例具有获取和设置属性的便捷方法,但CypherNodeCypherRelationship实例则没有,因此调用props ,您将可以访问关系的属性。

You might want to take a look at the CypherRelationship code. 您可能需要看一下CypherRelationship代码。 https://github.com/neo4jrb/neo4j-core/blob/master/lib/neo4j-server/cypher_relationship.rb is the bulk of it but it inherits from https://github.com/neo4jrb/neo4j-core/blob/master/lib/neo4j/relationship.rb , which is mostly an abstract class but it also provides a few other methods. 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 ,主要是一个抽象类,但它还提供了一些其他方法。 It has a pretty basic public interface, mostly convenience methods for working with the relationships. 它具有一个非常基本的公共接口,其中大多数是处理关系的便捷方法。 CypherNode is very similar: https://github.com/neo4jrb/neo4j-core/blob/master/lib/neo4j-server/cypher_node.rb . CypherNode非常相似: https : //github.com/neo4jrb/neo4j-core/blob/master/lib/neo4j-server/cypher_node.rb

In general, my recommendation is to define models using Neo4j::ActiveRel for any relationships that you plan on working with as objects in Ruby. 通常,我的建议是使用Neo4j::ActiveRel为计划在Ruby中作为对象使用的任何关系定义模型。 You can find the docs for it at http://neo4jrb.readthedocs.io/en/v7.0.2/ActiveRel.html . 您可以在http://neo4jrb.readthedocs.io/en/v7.0.2/ActiveRel.html上找到该文档的文档。

Two other notes: 另外两个注意事项:

  • You will receive Structs instead of instances of CypherNode / CypherRelationship or your model classes if your query is instructed to return properties instead of complete objects. 如果指示查询返回属性而不是完整对象,则您将收到结构体而不是CypherNode / CypherRelationship实例或模型类。

  • If you use the Cypher DSL instead of passing the query in, you can use the pluck method and receive Arrays of objects instead of structs, if you'd like. 如果您使用Cypher DSL而不是传递查询,则可以使用pluck方法并根据需要接收对象数组而不是结构。 return(symbols).to_a will work, too. 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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM