0

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

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");

不幸的是,文档一开始就非常好,然后当你建立关系时就往南走。

2012 年 3 月 29 日更新

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

        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));
            }
        }

活动节点创建良好。place 节点创建良好。现在尝试获取活动节点时会引发错误。这是一个相当大的堆栈跟踪,所以我将尝试在这里解释:

执行请求时收到异常。

查询是:gv(p0).in(p1).filter{ it[p2] == p3 }.drop(p4).take(p5)._()

例外情况是:值不能为空。参数名称:键 System.ArgumentNullException:值不能为空。参数名称:System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add) ... 原始响应正文为: [ { “outgoing_relationships”:“http://localhost:7474/db/data/node/2/relationships/out”,“data”:{“Name”:“Aerobics”,“Id”:2},“all_typed_relationships”: “http://localhost:7474/db/data/node/2/relationships/all/{-list|&|types}”,“遍历”:“http://localhost:7474/db/data/node/ 2/traverse/{returnType}”、“self”:“http://localhost:7474/db/data/node/2”、“property”:“http://localhost:7474/db/data/node/ 2/属性/{key}",

当键为空时将项目添加到字典时要做的事情。问题是,我在调试时看不到任何空值,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();

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

今天下午

开始试验 Gremlin 查询:

gv(0).inE.filter{it.label=="ACTIVITY_BELONGS_TO"}.outV.filter{it.Id==1}.Name

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

_graphClient.RootNode.InE(ActivityBelongsTo.TypeKey).OutV(b => 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)._()

这很好用。这里有些东西很臭……也许我应该尝试其他库,尽管我喜欢反序列化支持。叹...

认为也许原始查询会起作用。没有!此方法不再接受字符串和所需的 GremlinQuery 我不知道你该怎么做。咕咕咕咕咕咕咕咕。

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();
4

1 回答 1

1

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

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

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

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

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

    SELECT * FROM ... WHERE
    

    因此,您需要将节点附加到根节点是有意义的。这是来自 FrictionFreeApp 的示例:

    var node = graphClient.Create(
            user,
            new UserBelongsTo(rootNode));
    
于 2012-03-29T10:23:43.980 回答