我正在使用的模型的一些伪代码:
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();