Псевдокод модели, с которой я работаю:
User { int Id, string Username }
Activity { int Id, string Name }
Place { int Id, string Name }
По сути, у меня есть группа пользователей, и они принадлежат к определенным местам (отношения многие ко многим в мире RDBMS). Теперь, когда я создал все узлы, я хотел бы создать отношения между ними. Я считаю, что для этого мне нужно получить ссылки на каждый узел, а затем просто создать связь между ними.
Примечание: пока никаких отношений не существует. Похоже, что в некоторых примерах они добавили узлы User с отношением, которое указывает на 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));
}
}
Узлы активности созданы нормально. Узел места создан нормально. Теперь возникает ошибка при попытке получить код активности. Это довольно большая трассировка стека, поэтому я попытаюсь перефразировать здесь:
Получено исключение при выполнении запроса.
Запрос был: g.v (p0) .in (p1) .filter {it [p2] == p3
} .Drop (р4) .Снять (P5) ._ ()
Исключением было: значение не может быть нулевым. Имя параметра: ключ
System.ArgumentNullException: значение не может быть нулевым. Имя параметра: ключ
в System.Collections.Generic.Dictionary`2.Insert (ключ TKey, TValue
значение, логическое добавление) ... Необработанное тело ответа было: [{
"исходящие_отношения":
"http://localhost:7474/db/data/node/2/relationships/out"," данные ": {
"Имя": "Аэробика", "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}"," Я "
: "http://localhost:7474/db/data/node/2"," свойство ":
«http://localhost:7474/db/data/node/2/properties/{key}",
"outgoing_typed_relationships":
«http://localhost:7474/db/data/node/2/relationships/out/{-list|&|types}",
"свойства": "http://localhost:7474/db/data/node/2/properties",
"входящие_отношения":
"http://localhost:7474/db/data/node/2/relationships/in"," расширения "
: {}, "create_relationship":
«http://localhost:7474/db/data/node/2/relationships",
"paged_traverse":
«http://localhost:7474/db/data/node/2/paged/traverse/{returnType}{?pageSize,leaseTime}",
"all_relationships":
«http://localhost:7474/db/data/node/2/relationships/all",
"input_typed_relationships":
«http://localhost:7474/db/data/node/2/relationships/in/{-list|&|types}"
}]
Что делать при добавлении элемента в словарь при нулевом ключе. Проблема в том, что я не вижу нулей, когда я отлаживаюсь на своем конце, активность 1 есть, RootNode есть, TypeKey является константной строкой.
Мне почти интересно, стоит ли мне просто хранить созданные узлы в массиве или словаре, а затем просто работать с 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:
g.v (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 Я понятия не имею, как вам. Grooooooooooooooooan.
var users = graphClient.ExecuteGetAllNodesGremlin<IsCustomer>("g.v(0).out('IsCustomer'){it.'Name' == 'BobTheBuilder'}");
Обновление 3/30/12
Создан новый проект, все ниже работает нормально. Супер запутался, почему это будет работать здесь ... :( Может быть, различия в версии, я понятия не имею.
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();