0

GraphDb side

Vertex:User

Edge:Has

Vertex:Car

Object Side

public class User {  
    public string Name { get; set; }

    [GraphEdge("HAS_CAR")]
    public ICollection<Car> Cars { get; set; }
}

Problem

I want to get User X with Cars property from Neo4J via Gremlin? (I'm using Neo4jClient)

It's so similar Include method of Linq to Entity..

Best regards

Community
  • 1
  • 1
Oguz Karadenizli
  • 3,449
  • 6
  • 38
  • 73

2 Answers2

1

Assuming a graph like this:

Sample graph

You would use a Gremlin query like this to retrieve all of the cars, for all users:

g.v(0).out('HAS_USER').out('HAS_CAR')

Now, lets filter it down to just the red cars:

g.v(0).out('HAS_USER').out('HAS_CAR').filter { it.Color == "Red" }

Finally, you want the users instead of the cars. It's easiest to think of Gremlin working like an actual gremlin (little creature). You've told him to run to the users, then down to each of the cars, then to check the color of each car. Now you need him to go back to the users that he came from. To do this, we put a mark in the query like so:

g.v(0).out('HAS_USER').as('user').out('HAS_CAR').filter { it.Color == "Red" }.back('user')

To write this in C# with Neo4jClient is then very similar:

graphClient
    .RootNode
    .Out<User>(HasUser.TypeKey)
    .As("user")
    .Out<Car>(HasCar.TypeKey, c => c.Color == "Red")
    .BackV<User>("user")

The only difference here is that you need to use BackE or BackV for edges and vertexes respectively intead of just Back. This is because in the staticaly typed world of C# we need to use different method names to be able to return different enumerator types.

I hope that helps! :)

-- Tatham

Tatham Oddie
  • 4,290
  • 19
  • 31
  • I updated question. I'm so unlucky person because of borning on Microsoft side. We don't have "Spring Data Neo4j". Maybe this is a little object-graph mapping question. I want to get User object with loaded Cars property from Neo4j. How can I achieve this transparently? GraphEdgeAttribute? – Oguz Karadenizli Apr 30 '12 at 02:02
  • Ok, now I understand your question better. I will write another answer. – Tatham Oddie Apr 30 '12 at 02:27
0

Oğuz,

Now that you have updated the question, I understand it better.

GraphEdgeAttribute is not part of Neo4jClient, so I'm not sure where it has come from.

In Neo4jClient, we do not load deep objects. That is, we will not follow properties and load further collections. We do this because a) it would require us to do lots of roundtrips to the server and b) we think you should be explicit about what data you actually want to load. We do not want to be an equivalent to the Spring Data for Neo4j project because I do not believe it is a good approach.

It sounds like you might want to look at Cypher instead of Gremlin. That will let you load data as tables, including projections from multiple nodes.

-- Tatham

Tatham Oddie
  • 4,290
  • 19
  • 31
  • I'm getting your answer "by design" :) Thanks a lot. I'm setting this as "Accepted Answer". GraphEdgeAttribute is feature suggestion from me. I tried to find this feature in linq to entity,db4o. On cypher side it does not make any sense to get Nodes-Relations (Classes-RelatedProperties) as Table and convert them to back objects again. There must be better approach for this: – Oguz Karadenizli Apr 30 '12 at 02:56
  • graphClient .RootNode .Out(HasUser.TypeKey) .LoadOut(HasCar.TypeKey,c=>c.Color=="Red").AsProperty("Cars") – Oguz Karadenizli Apr 30 '12 at 02:58
  • Or graphClient.RootNode.Out(HasUser.TypeKey).LoadProperty("Cars",node=>node.Out(HasCar.TypeKey)) This is better maybe:) Yes, there is no need to GraphAttribute for this solution. – Oguz Karadenizli Apr 30 '12 at 03:00
  • a) Real roundtrip is to getting User and User's Cars seperately b) There is no problem in my solution, I'm explicitly saying Get User node with related Cars node – Oguz Karadenizli Apr 30 '12 at 03:06
  • The other design requirement we gave ourselves is that we mirror the Gremlin API. I'm hesitant (but not totally against) adding extra methods. – Tatham Oddie Apr 30 '12 at 05:11
  • Is there multi-query option for neo4jclient( or neo4j). What is the best way for getting two users with their cars? – Oguz Karadenizli May 02 '12 at 22:31
  • You'll want to use Cypher to retrieve such a projection. – Tatham Oddie May 10 '12 at 23:21
  • is using Cypher means two times convertion? Node.Relation-> TabularData -> ObjectGraph. I'm trying to find Fluent(Transparent) api. Because Graph->Tabular->Object convertion is getting overhead! – Oguz Karadenizli May 11 '12 at 00:06
  • As example, could you send Cypher Query sample for basic query I gave 6 comments ago? – Oguz Karadenizli May 11 '12 at 00:07