used - ¿Puede Neo4j almacenar un diccionario en un nodo?
neo4j pagina oficial (1)
Estoy trabajando en c # y uso neo4jclient. Sé que neo4jclient puede crear un nodo si le paso un objeto de clase (lo he intentado) Ahora en mi clase quiero agregar una propiedad de diccionario, esto no funciona. Mi código:
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();
El User
contiene una propiedad que es un Dictionary
en C #. Al ejecutar el cifrado muestra el error
MatchError: Map() (of class scala.collection.convert.Wrappers$JMapWrapper)
¿Alguien puede ayudarme?
Por defecto, Neo4j no se ocupa de los diccionarios (Maps en Java) por lo que su única solución real aquí es usar un serializador personalizado y serializar el diccionario como una propiedad de cadena ...
El siguiente código solo funciona para el tipo dado, y querrás hacer algo similar para que puedas usar el manejo predeterminado donde sea posible, y solo usar este convertidor para tu tipo:
//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);
}
}
Luego para usar en Neo4jClient:
var client = new GraphClient(new Uri("http://localhost:7474/db/data/"));
client.Connect();
client.JsonConverters.Add( new ThingWithDictionaryJsonConverter());
Luego usará ese convertidor cuando pueda.