如何使用Neo4jClient获取特定的Neo4j节点

时间:2012-03-28 19:46:03

标签: neo4j neo4jclient

我正在使用的模型的一些伪代码:

User { int Id, string Username }
Activity { int Id, string Name }
Place { int Id, string Name }

基本上我有一堆用户,他们属于某些地方(RDBMS世界中的多对多关系)。我现在想要做的就是创建所有节点已经创建了它们之间的关系。要做到这一点,我相信我需要获得对每个节点的引用,然后简单地创建它们之间的关系。

注意:到目前为止还没有任何关系。它看起来像在一些示例中他们添加了具有指向RootNode的关系的用户节点,但我不知道为什么。我不确定我是否需要这样做。

更多伪代码:

var userRef = _graphClient...GetUserNodeWhereIdEquals(user.Id);
// or something like _graphClient.OutV<User>("[[id={0}]]", user.Id)
// or even just _graphClient.V<User>(id == user.Id)
var placeRef = _graphClient...GetPlaceNodeWhereIdEquals(place.Id);

_graphClient...CreateRelationshipBetween(userRef, placeRef, "belongs_to");

不幸的是,文档开始时非常好,然后当你找到关系时向南走。

更新3/29/12

这是我到目前为止的代码:

        foreach (var a in _activityTasks.GetAll())
        {
            _graphClient.Create(a, new ActivityBelongsTo(_graphClient.RootNode));
        }
        foreach (var p in _placeTasks.GetAll().Take(1))
        {
            var placeNode = _graphClient.Create(p, new PlaceBelongsTo(_graphClient.RootNode));
            foreach (var activity in p.Activities)
            {
                Activity activity1 = activity;
                var activityNode = _graphClient.RootNode.In<Activity>(ActivityBelongsTo.TypeKey, a => a.Id == activity1.Id).SingleOrDefault();
                _graphClient.CreateRelationship(placeNode, new PlaceHasActivity(activityNode.Reference));
            }
        }

活动节点创建得很好。地点节点创建正常。尝试获取activityNode时,现在会抛出错误。这是一个相当大的堆栈跟踪,所以我试着在这里解释:

  

执行请求时收到异常。

     

查询是:g.v(p0).in(p1).filter {it [p2] == p3   } .drop(P4)。取(P5)._()

     

例外是:值不能为空。参数名称:key   System.ArgumentNullException:Value不能为null。参数名称:key   在System.Collections.Generic.Dictionary`2.Insert(TKey键,TValue   value,Boolean add)...原始响应主体是:[{   “outgoing_relationships”:   “http:// localhost:7474 / db / data / node / 2 / relationships / out”,“data”:{   “姓名”:“健美操”,“身份证”:2},“all_typed_relationships”:   的 “http://本地主机:7474 /分贝/数据/节点/ 2 /关系/所有/ {-list |&安培; |类型}”,   “遍历”:   “http:// localhost:7474 / db / data / node / 2 / traverse / {returnType}”,“self”   :“http:// localhost:7474 / db / data / node / 2”,“property”:   的 “http://本地主机:7474 /分贝/数据/节点/ 2 /属性/ {键}”,   “outgoing_typed_relationships”:   的 “http://本地主机:7474 /分贝/数据/节点/ 2 /关系/缩小/ {-list |&安培; |类型}”,   “properties”:“http:// localhost:7474 / db / data / node / 2 / properties”,   “incoming_relationships”:   “http:// localhost:7474 / db / data / node / 2 / relationships / in”,“extensions”   :{},“create_relationship”:   的 “http://本地主机:7474 /分贝/数据/节点/ 2 /关系”,   “paged_traverse”:   的 “http://本地主机:{?的pageSize,leaseTime} 7474 /分贝/数据/节点/ 2 /寻呼/横向移动/ {返回类型}”,   “all_relationships”:   的 “http://本地主机:7474 /分贝/数据/节点/ 2 /关系/所有”,   “incoming_typed_relationships”:   的 “http://本地主机:7474 /分贝/数据/节点/ 2 /关系/中/ {-list |&安培; |类型}”   }]

当键为空时将项添加到Dictionary时要做的事情。问题是,当我在我的端调试时没有看到任何空值,activity1在那里,RootNode在那里,TypeKey是一个const字符串。

我几乎想知道我是否应该将自己创建的节点保留在数组或字典中,然后再使用NodeReference。这就是我接下来要尝试的。

当天上午晚些时候

这似乎可以将所有内容加载到图数据库中:

var activityNodes = _activityTasks.GetAll().ToDictionary(a => a.Id, a => _graphClient.Create(a, new ActivityBelongsTo(_graphClient.RootNode)));

        foreach (var p in _placeTasks.GetAll())
        {
            var placeNode = _graphClient.Create(p, new PlaceBelongsTo(_graphClient.RootNode));
            foreach (var activity in p.Activities)
            {
                _graphClient.CreateRelationship(placeNode, new PlaceHasActivity(activityNodes[activity.Id]));
            }
        }

        foreach (var u in _userTasks.GetAllUserGraph())
        {
            var userNode = _graphClient.Create(u, new UserBelongsTo(_graphClient.RootNode));
            foreach(var activity in u.Activities)
            {
                _graphClient.CreateRelationship(userNode, new UserParticipatesIn(activityNodes[activity.Id]));
            }
        }

现在问题与我以前的问题类似。现在我想获得一个与RootNode有关系的活动:

Node<Activity> activity = _graphClient
                            .RootNode
                            .In<Activity>(ActivityBelongsTo.TypeKey, a => a.Id == 1)
                            .SingleOrDefault();

再次抛出键值不能为null异常。我想我需要更多地研究gremlin语法。我猜这个问题就在那里。

今天下午

开始尝试Gremlin查询:

g.v(0){.inE.filter it.label == “ACTIVITY_BELONGS_TO”}。outV.filter {it.Id == 1}请将.Name

工作正常。我尝试使用neo4jClient语法复制它:

_graphClient.RootNode.InE(ActivityBelongsTo.TypeKey).OutV(b =&gt; b.Id == 1).SingleOrDefault();

相同的空例外,它吐出:

g.v(p0).inE.filter{ it[p1].equals(p2) }.outV.filter{ it[p3] == p4 }.drop(p5).take(p6)._()

除了结束之外,对我来说是正确的。尽管如此:

g.v(0).inE.filter{it.label=="ACTIVITY_BELONGS_TO"}.outV.filter{it.Id==1}.drop(0).take(1)._()

这很好用。这里有点臭...也许我应该尝试其他库,虽然我喜欢de / serialization支持。叹息...

想到也许原始查询会起作用。不!这个方法不再接受字符串和所需的GremlinQuery我不知道你怎么做。 Grooooooooooooooooan。

var users = graphClient.ExecuteGetAllNodesGremlin<IsCustomer>("g.v(0).out('IsCustomer'){it.'Name' == 'BobTheBuilder'}");

2012年3月30日更新

创建了一个新项目,下面的一切工作正常。超级迷茫为什么它会在这里工作... :(也许版本差异,我不知道。

        var client = new GraphClient(new Uri("http://localhost:7474/db/data"));
        client.Connect();

        client.Create(new User { Id = 1, Username = "joe" }, new UserBelongsTo(client.RootNode));
        client.Create(new User { Id = 2, Username = "cloe" }, new UserBelongsTo(client.RootNode));
        client.Create(new Activity { Id = 1, Name = "Bocce Ball" }, new ActivityBelongsTo(client.RootNode));
        client.Create(new Activity { Id = 2, Name = "Programming" }, new ActivityBelongsTo(client.RootNode));

        var user = client.RootNode.In<User>(UserBelongsTo.TypeKey, u=>u.Id == 1).SingleOrDefault();
        var activity = client.RootNode.In<Activity>(ActivityBelongsTo.TypeKey, a=>a.Id == 1).SingleOrDefault();
        client.CreateRelationship(user.Reference, new Plays(activity.Reference));

        user = client.RootNode.In<User>(UserBelongsTo.TypeKey, u => u.Id == 1).SingleOrDefault();
        activity = client.RootNode.In<Activity>(ActivityBelongsTo.TypeKey, a => a.Id == 1).SingleOrDefault();

1 个答案:

答案 0 :(得分:1)

我刚刚开始。我建议你查看这个博客: http://romikoderbynew.com/2011/07/30/neo4jclient-primer/

另外,请查看http://frictionfree.org及其源代码(在about部分中)以获取更多示例。

  • 在现有关系上创建关系 - 据我所知,这是可能的。但是,在创建节点时,它们似乎更容易关联。来自博客:
  

您还可以在现有节点之间创建关系。   graphClient.CreateRelationship(customerNodeReference,new   说(languageNode.Reference));

  • RootNode - 我相信你需要从一个节点开始查询,我认为你不能做一个

    SELECT * FROM ... WHERE
    

    因此,您需要将节点附加到根节点是有意义的。这是FrictionFreeApp的一个例子:

    var node = graphClient.Create(
            user,
            new UserBelongsTo(rootNode));