Neo4j 可以在节点中存储字典吗?

Posted

技术标签:

【中文标题】Neo4j 可以在节点中存储字典吗?【英文标题】:Can Neo4j store a dictionary in a node? 【发布时间】:2014-04-17 11:42:02 【问题描述】:

我正在使用 c# 并使用 neo4jclient。 如果我将类对象传递给它,我知道 neo4jclient 可以创建一个节点(我已经尝试过了) 现在在我的课堂上我想添加一个字典属性,这不起作用。 我的代码:

 GraphClient client = getConnection();
 client.Cypher
       .Merge("(user:User  uniqueIdInItsApp: id , appId: appId )")
       .OnCreate()
       .Set("user = newUser")
       .WithParams(new
       
           id = user.uniqueIdInItsApp,
           appId = user.appId,
           newUser = user
       )
       .ExecuteWithoutResults();

User 包含一个属性,该属性是 C# 中的 Dictionary。 执行密码时显示错误

MatchError: Map() (of class scala.collection.convert.Wrappers$JMapWrapper)

谁能帮帮我?

【问题讨论】:

【参考方案1】:

默认情况下,Neo4j 不处理字典(Java 中的地图),因此您唯一真正的解决方案是使用自定义序列化程序并将字典序列化为字符串属性...

下面的代码只适用于给定的类型,你会想要做一些类似的事情,这样你就可以尽可能使用默认处理,并且只对你的类型使用这个转换器:

//This is what I'm serializing
public class ThingWithDictionary

    public int Id  get; set; 
    public IDictionary<int, string> IntString  get; set; 


//This is the converter
public class ThingWithDictionaryJsonConverter : JsonConverter

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    
        var twd = value as ThingWithDictionary;
        if (twd == null)
            return;

        JToken t = JToken.FromObject(value);
        if (t.Type != JTokenType.Object)
        
            t.WriteTo(writer);
        
        else
        
            var o = (JObject)t;
            //Store original token in a temporary var
            var intString = o.Property("IntString");
            //Remove original from the JObject
            o.Remove("IntString");
            //Add a new 'InsString' property 'stringified'
            o.Add("IntString", intString.Value.ToString());
            //Write away!
            o.WriteTo(writer);
        
    

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    
        if (objectType != typeof(ThingWithDictionary))
            return null;

        //Load our object
        JObject jObject = JObject.Load(reader);
        //Get the InsString token into a temp var
        var intStringToken = jObject.Property("IntString").Value;
        //Remove it so it's not deserialized by Json.NET
        jObject.Remove("IntString");

        //Get the dictionary ourselves and deserialize
        var dictionary = JsonConvert.DeserializeObject<Dictionary<int, string>>(intStringToken.ToString());

        //The output
        var output = new ThingWithDictionary();
        //Deserialize all the normal properties
        serializer.Populate(jObject.CreateReader(), output);

        //Add our dictionary
        output.IntString = dictionary;

        //return
        return output;
    

    public override bool CanConvert(Type objectType)
    
        //Only can convert if it's of the right type
        return objectType == typeof(ThingWithDictionary);
    

然后在 Neo4jClient 中使用:

var client = new GraphClient(new Uri("http://localhost:7474/db/data/"));
client.Connect();
client.JsonConverters.Add( new ThingWithDictionaryJsonConverter());

它会在可能的情况下使用该转换器。

【讨论】:

谢谢,克里斯~我也用类似的方法来解决它 嗨,克里斯,感谢您的回答。我遇到了一个问题,每次我使用 graphClient 运行查询时,传递给 ReadJson 的序列化程序参数为空...这是代码 sn-p,如果您有任何见解,我将不胜感激...此时我我正在查看 GitHub 上的 Neo4jClient 源代码:GraphClient.Cypher .Create($"(e:Person entity)") .WithParam("entity", node) .Return(e=>e.As( )).结果 嗨@MichelTriana 我可能需要更多的工作 - 你能发电子邮件/github/新问题吗?如果可以的话我会帮忙的!

以上是关于Neo4j 可以在节点中存储字典吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何将这种图存储在 neo4j 中以进行快速遍历?

在Neo4j中,我们如何使用graphql将生成查询后获得的键值对存储到另一个现有节点?

neo4j是啥?怎么配置?能单独使用吗?

Neo4j HA环境配置

neo4j cypher 节点可以模糊匹配么

neo4j-简介,安装