Написание запроса Neo4J Cypher в C # - PullRequest
0 голосов
/ 28 августа 2018

У меня есть приложение MVC Asp.Net, которое подключено к базе данных Neo4j. В моей базе данных есть связь (m:Movie)<-[r:HAS_WATCHED_MOVIE]-(u:User) между movie и user сущностями.

То, что я хочу сделать, это вернуть IEnumerable<Movie>, который содержит 3 лучших фильма (лучшие фильмы - это фильмы с большинством HAS_WATCHED_MOVIE отрывков) в порядке убывания.

Я уже выяснил запрос Cypher, чтобы сделать это, и он выглядит так:

MATCH (m:Movie)<-[r:HAS_WATCHED_MOVIE]-(b) 
RETURN m, COUNT(r) 
ORDER BY COUNT(r) DESC 
LIMIT 3

Поскольку я новичок в Neo4j C # клиенте, я не уверен, как написать этот запрос в c #?

1 Ответ

0 голосов
/ 29 августа 2018

Использование Neo4jClient

var client = new BoltGraphClient("bolt://localhost:7687", "neo4j", "neo");
client.Connect();

var query = client.Cypher
                  .Match("(m:Movie)<-[r:HAS_WATCHED_MOVIE]-(b)")
                  .Return((m,r) => new { 
                      Movie = m.As<Movie>(), 
                      Count = r.Count()
                   })
                  .OrderByDescending("Count")
                  .Limit(3);;

foreach(var result in query.Results)
   Console.WriteLine($"'{result.Movie.Title}' had {result.Count} watchers");

Для этого у меня есть Movie класс, определенный как:

public class Movie{
    [JsonProperty("title")]
    public string Title {get;set;}
}

Использование Neo4j-Driver

using (var driver = GraphDatabase.Driver("bolt://localhost:7687", AuthTokens.Basic("neo4j", "neo")))
{
    using (var session = driver.Session())
    {
        using (var tx = session.BeginTransaction())
        {
            IStatementResult results = tx.Run(
            @"MATCH (m:Movie)<-[r:HAS_WATCHED_MOVIE]-(b) 
              RETURN m, COUNT(r)
              ORDER BY COUNT(r) DESC
              LIMIT 3");
            foreach (IRecord result in results)
            {
                var node = result["m"].As<INode>();
                var title = node.Properties["title"]?.As<string>();
                var count = result["COUNT(r)"].As<long>();

                var movie = new Movie {
                      Title = title,
                };

                Console.WriteLine($"'{movie.Title}' had {count} watchers");
            }
        }
    }
}

NB. Я только сделал бит new Movie в этом, как вы говорите, вы хотели получить ответ IEnumerable<Movie>.

Мысли

Neo4jClient не возвращает IEnumerable<Movie>, так как вы используете COUNT вызов в RETURN, вам нужно сделать что-то вроде:

var query = gc.Cypher
        .Match("(m:Movie)<-[r:HAS_WATCHED_MOVIE]-(b)")
        .With("m, COUNT(r) AS count")
        .Return((m, r) => m.As<Movie>())
        .OrderByDescending("count")
        .Limit(3);

Где вы используете WITH, чтобы сделать COUNT перед возвращением. У вас нет , чтобы сделать это с версией Neo4j-Driver, поскольку вы можете подделать ее после факта, но я все равно изменил бы запрос, если все, что вам нужно, это Movie на:

IStatementResult results = tx.Run(
            @"MATCH (m:Movie)<-[r:HAS_WATCHED_MOVIE]-(b) 
              WITH m, COUNT(r) AS count
              RETURN m
              ORDER BY count DESC
              LIMIT 3");
...