Получить все связанные узлы, запрос Cypher в Neo4jClient .NET

У меня есть метод, который выполняет запрос Cypher, который я хотел бы вернуть всем узлам и их именам, которые имеют связь с указанным узлом (64) в запросе:

start n = node(64) match (n)--(x) return x.Name;

Теперь, когда я пытаюсь сделать это в своем коде, он не хочет работать. Вот мой метод:

public string GetAllFirstLevelRelatives(long NodeId)
{

    string QueryResult = null;

    try
    {
        var query = client_connection
            .Cypher
            .Start(NodeId, client_connection.RootNode)
            .Match(NodeId, "--(x)")
            .Return<Node<GraphNode>>("(x).name");

        QueryResult = query.Results.ToString();
    }
    catch (Exception e)
    {

    }
    return QueryResult;
}

Я хотел бы, чтобы этот запрос возвращал имена.

Может ли кто-нибудь помочь мне, пожалуйста?


person Mike Barnes    schedule 27.03.2013    source источник


Ответы (1)


Этот запрос:

start n = node(64) match n--x return x.Name;

Должен быть написан на С# как:

var query = graphClient
    .Cypher
    .Start("n", node)           // START n=node(123)
    .Match("n--x")              // MATCH n--x
    .Return<string>("x.Name");  // RETURN x.Name

Было несколько проблем с образцом кода, который вы предоставили:

  1. Скорее всего, будет несколько узлов, но ваш метод возвращал только один результат string. Вызов Results.ToString() вернет что-то вроде "System.Collections.IEnumberable<string>" вместо фактических результатов.
  2. Вам следует избегать передачи идентификаторов узлов как longs. Это побуждает вас использовать необработанные числа, чего делать не следует. Вместо этого используйте NodeReference. Любой запрос, который вы запускаете с помощью Neo4jClient, вернет вам объект NodeReference. Используйте это для запуска следующего запроса. Чтобы начать ваш самый первый запрос, мы предоставляем IGraphClient.RootNode. В основном вам никогда не нужно касаться идентификаторов узлов.
  3. Оборачивать любой код .NET в блок try {} catch {}, где раздел catch пуст, всегда нельзя. Пожалуйста, никогда не пишите это ни в каком коде. :)
  4. x.Name, вероятно, является строкой, но тогда вы вызывали это с помощью .Return<Node<GraphNode>>. Это в основном говорит: «загрузить x.Name (строку), но вернуть ее мне как Node<GraphNode>». Это не имеет особого смысла. Вы должны соответствовать типам.

Сочетая запрос, который я написал выше, и эти пункты, ваш метод должен выглядеть так:

public IEnumerable<string> GetAllFirstLevelRelatives(NodeReference node)
{
    var query = graphClient
        .Cypher
        .Start("n", node)           // START n=node(123)
        .Match("n--x")              // MATCH n--x
        .Return<string>("x.name");  // RETURN x.name

    return query.Results.ToList();
}

Чтобы улучшить это, вы должны воспользоваться нашей системой типов. Что такое "x" в вашем запросе? Давайте представим, что это фильм.

Вы должны создать класс, описывающий, что содержит узел фильма:

public class Movie
{
    public string Name { get; set; }
}

Этот класс должен быть «POCO» (простой старый объект класса), что означает, что он должен иметь только базовые свойства, а не методы или логику.

Затем используйте информацию этого типа в своем запросе:

public IEnumerable<Movie> GetAllRelatedMovies(NodeReference node)
{
    var query = graphClient
        .Cypher
        .Start("n", node)
        .Match("n--movie")
        .Return<Movie>("movie");

    return query.Results.ToList();
}

Теперь у вас есть список фильмов, а не просто список строк. Маловероятно, что вам понадобятся только названия фильмов, так что таким образом вы получите доступ ко всем свойствам.

person Tatham Oddie    schedule 28.03.2013
comment
Спасибо чувак, очень помог. - person Mike Barnes; 28.03.2013