问题
I use Neo4jClient and I want to get relation attribute by Variable length relationships (n:Users {id:1})-[r:FOLLOW*1..4]-(m:Users) RETURN r
how I can get node with attribute relation , for example :
Node[0]{id:1,name:"Oliver Stone"}
Node[1]{id:2,name:"Charlie Sheen"}
Node[2]{id:3,name:"Martin Sheen"}
Node[3]{id:4,name:"TheAmericanPresident"}
I should know , what is attribute relation between Node[0] and Node[2]? (attribute mean "FOLLOW" or "IGNORE")
回答1:
First up, if you are using [r:FOLLOW*1..4]
you already know the TypeKey
as it's in your code, if you want to get the TypeKey
for [r*1..4]
then you can use the below code, the main change is we're bringing back R
as IEnumerable<RelationshipInstance<object>>
rather than just straight RelationshipInstance<object>
.
var query = Client.Cypher
.Match("(n:User)-[r*1..4]-(m:User)")
.Where((UserEntity n) => n.Id == 1)
.Return((n, r, m) => new
{
N = n.As<UserEntity>(),
M = m.As<UserEntity>(),
R = r.As<IEnumerable<RelationshipInstance<object>>>() //<-- IEnumerable<T>
});
var res = query.Results;
foreach (var item in res.ToList())
foreach (var relationshipInstance in item.R)
Console.WriteLine("({0})-[:{1}]-({2})", item.N.Id, relationshipInstance.TypeKey, item.M.Id);
Now, imagine you have the following setup:
(Node:1)-[:IGNORE]->(Node:2)->(:FOLLOW)->(Node:3)
Running the above code will get you this as an output:
(1)-[:IGNORE]-(3)
(1)-[:FOLLOW]-(3)
You don't really know what the order is, and you have conflicting types. Imagining you are after the actual route rather than just the names (I realise this may not be the case), we need to change a few more bits of the query.
If you look into the RelationshipInstance
you are getting back, you'll see it has two properties: EndNodeReference
and StartNodeReference
, you'll also note that the Id
property of those has no relation to any Id you have in your objects. The Id
in this case relates to the actual Neo4j Id. To get meaningful data out of it, we'll need to get that Id, and that means using Node<T>
. Ideally we don't want to do this, but I'm unaware of any other way to get the routes at the present time.
var query = Client.Cypher
.Match("(n:User)-[r*1..4]-(m:User)")
.Where((UserEntity n) => n.Id == 1)
.Return((n, r, m) => new
{
N = n.As<Node<UserEntity>>(), //<-- Node<T>
M = m.As<Node<UserEntity>>(), //<-- Node<T>
R = r.As<IEnumerable<RelationshipInstance<object>>>()
});
foreach (var item in res.ToList())
foreach (var relationshipInstance in item.R)
Console.WriteLine("({0})-[:{1}]-({2})", item.N.Data.Id, relationshipInstance.TypeKey, item.M.Data.Id);
Now you've got all the relevant data for the relationships to piece it all together. If you look at one of the Node<T>
instances (N
or M
), you'll see you have a .Reference
property which will match to the .*NodeReference
properties on the RelationshipInstance
, with that information you can build up the actual TypeKey
by relation.
来源:https://stackoverflow.com/questions/25801597/get-relationship-nodes-by-variable-length-relationships-in-neo4j-using-neo4jclie