Neo4j 可以在节点中存储字典吗? [英] Can Neo4j store a dictionary in a node?

查看:23
本文介绍了Neo4j 可以在节点中存储字典吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I an working on c# and use neo4jclient. I know neo4jclient can create a node if I pass a class object to it (I have tried it) Now in my class I want to add a dictionary property, this doesn't work. My code:

 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.执行密码时显示错误

The User contains a property that is a Dictionary in C#. When executing the cypher it shows the error

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

有人可以帮我吗?

推荐答案

默认情况下,Neo4j 不处理 Dictionaries(Java 中的 Maps),因此这里唯一真正的解决方案是使用自定义序列化程序并将字典序列化为字符串财产...

By default Neo4j doesn't deal with Dictionaries (Maps in Java) so your only real solution here is to use a custom serializer and serialize the dictionary as a string property...

下面的代码仅适用于给定的类型,您需要做一些类似的事情,以便尽可能使用默认处理,并且只为您的类型使用此转换器:

The code below only works for the type given, and you'll want to do something similar so you can use the default handling where possible, and only use this converter for your type:

//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 中使用:

Then to use in Neo4jClient:

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

然后它会在可能的情况下使用该转换器.

It'll then use that converter when it can.

这篇关于Neo4j 可以在节点中存储字典吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆