用 C# 编写 Neo4J Cypher 查询

Mil*_*lan 0 c# neo4j cypher neo4jclient

我有一个连接到 Neo4j 数据库的 MVC Asp.Net 应用程序。在我的数据库中,实体(m:Movie)<-[r:HAS_WATCHED_MOVIE]-(u:User)之间存在关系。movieuser

我想要做的是按降序返回一个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
Run Code Online (Sandbox Code Playgroud)

由于我是 Neo4j C# 客户端的新手,我不确定如何在 C# 中编写此查询?

Chr*_*don 5

使用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");
Run Code Online (Sandbox Code Playgroud)

对于这个,我将我的Movie班级定义为:

public class Movie{
    [JsonProperty("title")]
    public string Title {get;set;}
}
Run Code Online (Sandbox Code Playgroud)

使用Neo4j 驱动

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");
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

注意。我只做了这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);
Run Code Online (Sandbox Code Playgroud)

在返回之前使用 aWITH来做的地方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");
Run Code Online (Sandbox Code Playgroud)