簡體   English   中英

使用Neo4j.Driver向Neo4j添加關系

[英]Add relation to Neo4j with Neo4j.Driver

我是Neo4j的C#開發人員。 我花了幾周的時間學習圖形概念並試用Cypher。 到目前為止,這是一個很好的體驗!

我現在嘗試通過官方C#驅動程序處理代碼中的一些真實數據。 我很驚訝地發現驅動程序只是API的包裝,而頂部沒有真正的.Net功能。

在創建節點時,我可以很好地使用以下模式創建Cypher語句:

CREATE (:Movie {tmdbId: {tmdbId}, imdbId: {imdbId}, title: {title}, originalTitle: {originalTitle}, collectionInfo: {collectionInfo}, genres: {genres}, releaseDate: {releaseDate}, plot: {plot}, tagline: {tagline}, originalLanguage: {originalLanguage}, tmdbPopularity: {tmdbPopularity}, tmdbVoteAverage: {tmdbVoteAverage}, tmdbVoteCount: {tmdbVoteCount}, budget: {budget}} )

參數集合是從對象自動生成的。 工作正常。 但是在創建關系時,出現意外錯誤。

這是我用來建立關系的語句。 通過ID查找源節點和目標節點。

MATCH (s:Person), (t:Movie) WHERE s.personId=35742 AND t.movieId=19404 CREATE (s)-[r:ACTED_IN {order: {order}, character: {character}}]->(t) RETURN r

我收到的錯誤是:

System.Reflection.TargetParameterCountException: 'Parameter count mismatch.'

參數集合的創建方法與上次相同。 它具有兩個屬性,分別為“ order”和“ character”。

我遺失的陳述中是否有錯誤?

    /// <summary>
    /// Add object as node in Neo4j database.
    /// All public properties will automatically be added as properties of the node.
    /// </summary>
    /// <param name="obj">Generic POCO object</param>
    /// <param name="label">Specify type name to be uses. Skip if you are satisfied with object type name.</param>
    public void AddNode(object obj, string label = null)
    {
        using (var session = _driver.Session())
        {
            label = label ?? obj.GetType().Name;
            var parameters = GetProperties(obj);
            var valuePairs = string.Join(", ", parameters.Select(p => $"{p.Key}: {{{p.Key}}}"));
            var statement = $"CREATE (:{label} {{{valuePairs}}} )";
            var result = session.Run(statement, parameters);
            Debug.WriteLine($"{result.Summary.Counters.NodesCreated} {label} node created with {result.Summary.Counters.PropertiesSet} properties");
        }
    }

    public void AddRelation(string sourceNodeName, string sourceIdName, string targetNodeName, string targetIdName, string relationName, object relation, string relationSourceIdName, string relationPropertyIdName)
    {
        using (var session = _driver.Session())
        {
            //MATCH(s:Person), (t:Person)
            //WHERE s.name = 'Source Node' AND t.name = 'Target Node'
            //CREATE(s) -[r:RELTYPE]->(t)
            //RETURN r           
            var parameters = GetProperties(relation);
            var sourceId = parameters[relationSourceIdName];
            var targetId = parameters[relationPropertyIdName];
            var properties = parameters.Where(p => p.Key != relationSourceIdName && p.Key != relationPropertyIdName).ToList();
            var valuePairs = string.Join(", ", properties.Select(p => $"{p.Key}: {{{p.Key}}}"));
            var statement = $"MATCH (s:{sourceNodeName}), (t:{targetNodeName}) WHERE s.{sourceIdName}={sourceId} AND t.{targetIdName}={targetId} CREATE (s)-[r:{relationName} {{{valuePairs}}}]->(t) RETURN r";

            var result = session.Run(statement, properties);
            Debug.WriteLine($"{result.Summary.Counters.RelationshipsCreated} {relationName} relations created with {result.Summary.Counters.PropertiesSet} properties");
        }
    }

    private static Dictionary<string, object> GetProperties(object obj)
    {
        var dictionary = new Dictionary<string, object>();
        foreach (var property in obj.GetType().GetProperties())
        {
            var propertyName = property.Name;
            var value = property.GetValue(obj);

            var array = value as string[];
            if (array != null)
            {
                value = string.Join(",", array);
            }
            if (value is DateTime)
            {
                var dateTime = (DateTime)value;
                value = dateTime.ToString("yyyy-MM-dd");
            }

            dictionary.Add(propertyName.ToCamelCase(), value);
        }
        return dictionary;
    }

布魯諾使我朝着正確的方向前進! Cypher和包裝器都沒有問題。 我的錯誤是過濾參數集合並返回屬性列表,而不是將其保留為字典。

調整后的工作方法現在如下所示:

    public void AddRelation(string fromNodeName, string fromIdName, string toNodeName, string toIdName, string relationName, object relation, string relationFromIdName, string relationToIdName)
    {
        using (var session = _driver.Session())
        {
            //MATCH(s:Person), (t:Person)
            //WHERE s.name = 'Source Node' AND t.name = 'Target Node'
            //CREATE(s) -[r:RELATIONTYPE]->(t)
            //RETURN r           
            var parameters = GetProperties(relation);
            var fromIdValue = parameters[relationFromIdName];
            var toIdValue = parameters[relationToIdName];
            var properties = parameters.Where(p => p.Key != relationFromIdName && p.Key != relationToIdName).ToDictionary(p => p.Key, p => p.Value);
            var valuePairs = string.Join(", ", properties.Select(p => $"{p.Key}: {{{p.Key}}}"));
            var statement = $"MATCH (s:{fromNodeName}), (t:{toNodeName}) WHERE s.{fromIdName}={fromIdValue} AND t.{toIdName}={toIdValue} CREATE (s)-[r:{relationName} {{{valuePairs}}}]->(t) RETURN r";
            var result = session.Run(statement, properties);
            Console.WriteLine($"{result.Summary.Counters.RelationshipsCreated} {relationName} relations created with {result.Summary.Counters.PropertiesSet} properties");
        }
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM