Skip to content

Instantly share code, notes, and snippets.

@tombatron
Created April 30, 2022 17:57
Show Gist options
  • Save tombatron/688f31065b6d07040d60b4f02af3c6ee to your computer and use it in GitHub Desktop.
Save tombatron/688f31065b6d07040d60b4f02af3c6ee to your computer and use it in GitHub Desktop.
Demonstration settings and getting JSON values within an array using JSONPath syntax with NReJSON.
// Make sure that the version of the RedisJson module that you're
// using is equal to or greater than version 20007. I'm using the
// following: redis/redis-stack-server:latest
using System.Text.Json;
using NReJSON;
using StackExchange.Redis;
// Let's define an example model instance to persist to Redis...
var example = new TestModel
{
Things = new []
{
new NestedModel { Id = 1, Value = "The First Value."},
new NestedModel { Id = 2, Value = "The Second Value."},
new NestedModel { Id = 3, Value = "The Third Value."},
}
};
// One time configuration of the JSON serializer for NReJSON to use.
NReJSONSerializer.SerializerProxy = new SystemTextJsonSerializerProxy();
var muxr = ConnectionMultiplexer.Connect("localhost");
var db = muxr.GetDatabase();
// Since I setup a JSON serializer the generic overload for the `JsonSetAsync`
// method is used and our example model instance is automatically serialized
// to JSON for us.
await db.JsonSetAsync("TestObject", example);
// Get and write out the `Value` property for the object in the "Things" collection
// that has an `Id` value of 2.
var initialValue = await db.JsonGetAsync<string>("TestObject", "$.Things[?(@.Id==2)].Value");
Console.WriteLine(initialValue);
// Using a JSONPath expression I'm targeting the `Value` property of the item in the "Things"
// collection and setting it to the string value "2nd value". Notice that I've had to add
// some double quotes here. Since there are two overloads for `JsonSetAsync` one that accepts a
// serialized JSON string and another that is generic and is intended to be used with an arbitrary
// type.
await db.JsonSetAsync("TestObject", "\"2nd value\"", "$.Things[?(@.Id==2)].Value");
// If you didn't want to quote the string, you could always cast the string value as an object
// and the serializer that was defined will be used to serialize the value.
// await db.JsonSetAsync("TestObject", (object)"2nd value", "$.Things[?(@.Id==2)].Value");
// Now we're going to re-get the target value by once again using the JSONPath that we used with the
// previous two commands.
var updatedValue = await db.JsonGetAsync<string>("TestObject", "$.Things[?(@.Id==2)].Value");
Console.WriteLine(updatedValue);
// Basic serializer proxy for System.Text.Json.
public class SystemTextJsonSerializerProxy : ISerializerProxy
{
public TResult? Deserialize<TResult>(RedisResult serializedValue) =>
serializedValue.IsNull ? default : JsonSerializer.Deserialize<TResult>(serializedValue.ToString() ?? "{}");
public string Serialize<TObjectType>(TObjectType obj) =>
JsonSerializer.Serialize(obj);
}
// The following are some example classes.
public class TestModel
{
public NestedModel[] Things { get; set; }
}
public class NestedModel
{
public int Id { get; set; }
public string Value { get; set; }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment