Как я могу получить конкретный узел Neo4j, используя Neo4jClient - PullRequest
0 голосов
/ 28 марта 2012

Псевдокод модели, с которой я работаю:

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

1 Ответ

1 голос
/ 29 марта 2012

Я тоже только начинаю. Я хотел бы предложить вам проверить этот блог: 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));
    
...