41
loading...
This website collects cookies to deliver better user experience
Customer
object as our model throughout our examples:public class Customer
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public int Age { get; set; }
}
docker run -p 6379:6379 redislabs/redismod
dotnet new console -n RedisOmComparison
RedisOmComparison
directory, and run dotnet add package Redis.OM
to install Redis OM.// Standard Redis
var muxer = await ConnectionMultiplexer.ConnectAsync("localhost");
var db = muxer.GetDatabase();
// Redis OM
var provider = new RedisConnectionProvider("redis://localhost:6379");
var bob = new Customer
{
Age = 35,
Email = "[email protected]",
FirstName = "Bob",
LastName = "Smith"
};
Document
Attribute, and then we'll decorate each of the properties with the Indexed
attribute. After this is done, our Customer object should look like this:[Document]
public class Customer
{
[Indexed(Sortable = true)] public string FirstName { get; set; }
[Indexed(Sortable = true)] public string LastName { get; set; }
[Indexed(Sortable = true)] public string Email { get; set; }
[Indexed(Sortable = true)] public int Age { get; set; }
}
Customer.cs
provider.Connection.CreateIndex(typeof(Customer));
RedisCollection<Customer>
, and simply insert a new customer into Redis.var customers = provider.RedisCollection<Customer>();
var customerId = await customers.InsertAsync(bob);
Customer:AGuid
as our key name to keep it simple.var keyName = $"Customer:{Guid.NewGuid()}";
HashSetAsync
method on the DB
object and passing in the properties/values of Bob
as field value pairs:await db.HashSetAsync(keyName, new HashEntry[]
{
new HashEntry(nameof(Customer.FirstName), bob.FirstName),
new HashEntry(nameof(Customer.LastName), bob.LastName),
new HashEntry(nameof(Customer.Email), bob.Email),
new HashEntry(nameof(Customer.Age), bob.Age)
});
await db.SortedSetAddAsync($"Customer:FirstName:{bob.FirstName}", keyName, 0);
await db.SortedSetAddAsync($"Customer:LastName:{bob.LastName}", keyName, 0);
await db.SortedSetAddAsync($"Customer:Email:{bob.Email}", keyName, 0);
await db.SortedSetAddAsync($"Customer:Age", keyName, bob.Age);
CreateIndex
once), creating a customer object is very straightforward:var customerId = await customers.InsertAsync(bob);
var keyName = $"Customer:{Guid.NewGuid()}";
await db.HashSetAsync(keyName, new HashEntry[]
{
new HashEntry(nameof(Customer.FirstName), bob.FirstName),
new HashEntry(nameof(Customer.LastName), bob.LastName),
new HashEntry(nameof(Customer.Email), bob.Email),
new HashEntry(nameof(Customer.Age), bob.Age)
});
await db.SetAddAsync($"Customer:FirstName:{bob.FirstName}", keyName);
await db.SetAddAsync($"Customer:LastName:{bob.LastName}", keyName);
await db.SetAddAsync($"Customer:Email:{bob.Email}", keyName);
await db.SortedSetAddAsync($"Customer:Age", keyName, bob.Age);
FindById
command:var alsoBob = await customers.FindByIdAsync(customerId);
HGETALL
and then build a new instance of the object from the hash, which takes a bit more effort:var bobHash = await db.HashGetAllAsync(keyName);
var manuallyBuiltBob = new Customer
{
Age = (int)bobHash.FirstOrDefault(x=>x.Name == "Age").Value,
FirstName = bobHash.FirstOrDefault(x=>x.Name == "FirstName").Value,
LastName = bobHash.FirstOrDefault(x=>x.Name == "LastName").Value,
Email = bobHash.FirstOrDefault(x=>x.Name == "Email").Value,
};
SELECT * FROM Customers WHERE FirstName = 'Bob'
. However, by default, Redis lacks the concept of a table scan to look up records by a given value. That's why earlier, we constructed secondary indexes for both types. So now, let's look at querying items by their values.FirstName
property in Redis OM, all you need is a simple LINQ statement:var bobsRedisOm = customers.Where(x => x.FirstName == "Bob");
var bobIds = await db.SortedSetRangeByRankAsync($"Customer:FirstName:Bob");
var bobsWithoutOm = new List<Customer>();
foreach (var id in bobIds)
{
var hash = await db.HashGetAllAsync(id.ToString());
bobsWithoutOm.Add(new Customer
{
Age = (int)hash.FirstOrDefault(x=>x.Name == "Age").Value,
FirstName = hash.FirstOrDefault(x=>x.Name == "FirstName").Value,
LastName = hash.FirstOrDefault(x=>x.Name == "LastName").Value,
Email = hash.FirstOrDefault(x=>x.Name == "Email").Value,
});
}
>=,<=,>,<,==
var under65RedisOm = customers.Where(x=>x.Age < 65);
var under65IdsWithoutRedisOm = db.SortedSetRangeByScore($"Customer:Age", 0, 65);
var under65WithoutRedisOm = new List<Customer>();
foreach (var id in under65IdsWithoutRedisOm)
{
var hash = await db.HashGetAllAsync(id.ToString());
under65WithoutRedisOm.Add(new Customer
{
Age = (int)hash.FirstOrDefault(x=>x.Name == "Age").Value,
FirstName = hash.FirstOrDefault(x=>x.Name == "FirstName").Value,
LastName = hash.FirstOrDefault(x=>x.Name == "LastName").Value,
Email = hash.FirstOrDefault(x=>x.Name == "Email").Value,
});
}
HSET
and pass in the key and the field/value pairs you'd like to update. However, when you're indexing items, you need to coordinate the indexes as well, at least when you're not using Redis OM:Save
on the collection:foreach (var customer in customers)
{
customer.Age += 1;
}
await customers.SaveAsync();
HashSet
on the key and each of the fields within it you want to update.await db.HashSetAsync(keyName, new HashEntry[]{new ("Age", bob.Age + 1), new("Email", "[email protected]")});
await db.SortedSetRemoveAsync($"Customer:Email:{bob.Email}", keyName);
await db.SortedSetAddAsync($"Customer:Email:@[email protected]", keyName, 0);
await db.SortedSetAddAsync($"Customer:Age", keyName, bob.Age + 1);
Unlink
on the item's key:provider.Connection.Unlink(customerId);
await db.KeyDeleteAsync(keyName);
await db.SortedSetRemoveAsync($"Customer:Email:{bob.Email}", keyName);
await db.SortedSetRemoveAsync($"Customer:FirstName:{bob.FirstName}", keyName);
await db.SortedSetRemoveAsync($"Customer:LastName:{bob.LastName}", keyName);
await db.SortedSetRemoveAsync($"Customer:Age", keyName);