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