Redis omによるCRUD.ネット- C


季節C# Advent 再び、そして、私のトピックのために、私が最近書いた図書館について話すつもりです.Redis OM . C CHERINEのアドベントのすべての貢献者に、そして、今年、それを組織するために、大きい感謝.あなたがまだしていないならば、コミュニティが今年出したすべてのすばらしい内容をチェックしてください.
REDISは、そのシンプルさとスピードのために愛されているNOSQLデータベースです.それらの2つの美徳は、それを作りますmost loved database 開発者によって.しかし、あなたがより複雑なオブジェクトを保存したいならば、redisに内在する問題があります.REDISはキー値データ構造ストアです.これは、データに対してCRUD(Read Update and Delete)操作を実行する場合、データにアクセスするのを気にする唯一の方法はあなたの鍵であるということです.しかし、我々は価値によってアイテムを見てみたいですか?これは物事がトリッキーでトリッキーになることができます、そしてそれはまた、どこの物語ですRedis OM 始まります.Redisの値によって項目を照会することは、それらのオブジェクトのために二次インデックスを手動で構築して、維持するために開発者の部分にかなりの量の仕事を必要とします.その後、クエリを実行するためにいくつかのコマンドを実行する必要があります.With Redis OM and RedisJSON , あなたのモデルを時間の前に構築することができますし、LINQインターフェイスを使用してクエリを実行します.

モデル


これを使うつもりですCustomer 例を通して我々のモデルとしてのオブジェクト
public class Customer
{
   public string FirstName { get; set; }
   public string LastName { get; set; }
   public string Email { get; set; }
   public int Age { get; set; }
}
我々は、顧客の任意のフィールドを検索したいと仮定します.それを念頭に置いて、Redis Omで何をしなければならないのか、永続的なストレージの基本的な操作のためにREDISを実行しなければならないことについて説明します.

設定


レイスを始める


まず、環境を設定します.次に、開発目的では、dockerを使ってREDISを実行します.
docker run -p 6379:6379 redislabs/redismod

プロジェクトの設定


次に、プロジェクトをセットアップします.最後に、コンソールアプリケーションとしてこれを実行します.
dotnet new console -n RedisOmComparison
CDの中にRedisOmComparison ディレクトリと実行dotnet add package Redis.OM Redis omをインストールするには

接続オブジェクトを初期化する


さて、2つの接続オブジェクトを初期化します.Redis OMセットアップのための標準REDISセットアップとRedisConnectionProviderのためのConnectionComplexer.プログラムで.cs実行する
// Standard Redis
var muxer = await ConnectionMultiplexer.ConnectAsync("localhost");
var db = muxer.GetDatabase();

// Redis OM
var provider = new RedisConnectionProvider("redis://localhost:6379");

初期化ボブ


それで、我々は一貫しています、我々は両方の例(Bob)の向こう側に同じCustomerオブジェクトを使用します
var bob = new Customer 
{
   Age = 35, 
   Email = "[email protected]", 
   FirstName = "Bob", 
   LastName = "Smith"
};

redis omでredisのインデックスオブジェクトを作成する


Redis omでREDISでオブジェクトを作成するには、我々の初期モデルから始めますが、いくつかの属性を追加します.第一に、私たちはクラスそのものをDocument 属性を指定し、それぞれのプロパティをIndexed 属性.これが完了したら、Customerオブジェクトは次のようになります.
[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

インデックスの作成


今、顧客にインデックスを付けて宣言したので、インデックスを作成します.これはインデックスごとに1回だけ行う必要があります.プログラムで.cs add :
provider.Connection.CreateIndex(typeof(Customer));

顧客を加える


すべてのそれを行うには、顧客を追加するにはRedisCollection<Customer> , そして、単にRedisに新しい顧客を挿入してください.
var customers = provider.RedisCollection<Customer>();
var customerId = await customers.InsertAsync(bob);

redis omのないredisのインデックスオブジェクトを作成する


Redis OMなしで索引付けされたオブジェクトを作成することは少し複雑です.我々は3つのステージを通過する必要があります.これは何かを追加するたびに実行する必要があります.
  • キー名を作成する
  • ハッシュにオブジェクトを写像して、ハッシュをつくってください
  • 各項目に関連するインデックスを更新する
  • キー名


    使いましょうCustomer:AGuid 私たちのキーの名前として簡単に保つ.
    var keyName = $"Customer:{Guid.NewGuid()}";
    

    オブジェクトのハッシュを作成する


    redis(モジュールなしで)のインデックス可能なオブジェクトを保存するときに使用する自然なデータ構造はredisハッシュです.REDISハッシュにオブジェクトを格納するには、READISキーと一緒にREADISに送ることができるフィールド値ペアのセットに分割する必要があります.これが完了すると、オブジェクトはREDISに実際に格納されます.を呼び出すことによって行うことができますHashSetAsync メソッドDB のプロパティと値Bob フィールド値のペアとして:
    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)
    });
    

    インデックスを設定する


    redis omとは異なり、インデックスは標準REDISで設定されていません.それぞれのインデックスフィールドは、独自のインデックスを保持する必要があります.この目的のために、各々のフィールドのために、我々は異なるソートされたセットを保ちます.各文字列フィールド名に対して、これは各値のソートされたセットになります.後で、あなたがRedisのアイテムを更新するとき、これらもまた更新される必要があります.インデックスを作成するには、次のコードを実行します
    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);
    

    比較


    したがって、Redis OMのインデックスを初期化するための予備ステップの後にCreateIndex 一度、顧客オブジェクトを作成するのはとても簡単です.
    var customerId = await customers.InsertAsync(bob);
    
    Redis Omなしでそうすること
    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);
    
    当然、前者ははるかに簡単です、そして、それは達成するためにredisへの一回の往復だけを必要とします!

    IDでREDISからデータを読み込む


    REDISにデータを挿入したので、どうやって読むことができますか?さて、1について考える2つの局面があります:どのように、あなたはオブジェクトを尋ねていますか?2 :どのようにあなたのオブジェクトをマーシャリングですか?
    あなたのオブジェクト1を問い合わせる方法の2つのタイプがあります:キー2 :値によって.前者の場合、問い合わせはどちらも簡単です.

    Redis omで


    Redis Omを使ってREDISからアイテムを読むにはFindById コマンド
    var alsoBob = await customers.FindByIdAsync(customerId);
    

    レイスノームなしで


    redisオームなしで、あなたは電話する必要がありますHGETALL それから、ハッシュからオブジェクトの新しいインスタンスを構築します.
    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,
    };
    

    Redisから値を読む


    これは物事が面白い取得を開始します.多くのデータベースユースケースは、値によって項目を見る能力を必要とします.たとえば、我々は伝統的なSQLデータベースで“ボブ”という名前のすべての顧客を見つけたいなら、私たちはSELECT * FROM Customers WHERE FirstName = 'Bob' . しかし、デフォルトでは、REDISは、指定された値でレコードを調べるためにテーブルスキャンの概念を欠いています.それゆえ、私たちは両方のタイプのために二次インデックスを構築しました.それでは、その値によって項目の問い合わせを見てみましょう.

    firstname redis omによるクエリ


    で検索するFirstName REDIS OMのプロパティ、必要なのは単純なLINQ文です:
    var bobsRedisOm = customers.Where(x => x.FirstName == "Bob");
    
    そして、そのコレクションが列挙されると、現在REDISのすべてのBOBSが顧客として設定されます.

    Redis Omのないfirstnameの問い合わせ


    Redis Omのないファーストネームでの問い合わせは、従来のようにより複雑です.今回は、すべての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,
        });
    }
    

    年齢Redisオームによる質問


    REDIS OMで年齢によって質問するために、我々は我々が数>=,<=,>,<,==
    var under65RedisOm = customers.Where(x=>x.Age < 65);
    

    Redisオームなしで年齢による質問


    Redis Omのない年齢による問い合わせは、どのようにストリングが働くかに似ています.この場合を除き、ソートされた設定に範囲クエリを送信します.
    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,
        });
    }
    

    REDISにおけるオブジェクトの更新


    REDISでオブジェクトを更新する仕組みはとても簡単です.ハッシュの場合は、単に呼び出しHSET そして、あなたが更新したいキーとフィールド/値のペアを渡します.ただし、インデックス項目を使用する場合は、少なくともRedis OMを使用していないときにインデックスを調整する必要があります.

    REDIS OMによるREDISのアイテムの更新


    Redis Omを使用してRedisの項目を更新するには、単に列挙されたコレクションと呼び出しの項目を変更しますSave コレクションには
    foreach (var customer in customers)
    {
        customer.Age += 1;
    }
    await customers.SaveAsync();
    
    これは、アイテムの更新内容にかかわらず同じです.

    REDIS OMのないREDISのアイテムの更新


    REDIS OMなしでREDISのアイテムを更新するには、まず項目を更新するための呼び出しを行う必要があります.だから、先に行くとレッドミスのメールなしで年齢属性を更新する方法を参照してください.

    データの更新


    データの更新はかなり簡単ですHashSet キーとその中の各フィールドに更新したい.
    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);
    

    インデックス項目の削除


    Redis omで


    redis omでredisの索引付け項目を削除するとき、呼び出しと同じくらい簡単ですUnlink 項目のキー
    provider.Connection.Unlink(customerId);
    

    レイスノームなしで


    Redis Omなしでは、キーを削除しなければならないことに加えて、付随するインデックスフィールドのすべてのセットに入ってキーを削除する必要があります.
    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);
    

    総括


    我々がこの記事を通して見たように、Redis OmがRedisでCRUD操作のすべてを実行しているとき、Redis Omは本当の恩恵です.それだけではなく、あなたがRedis Omのすべてを一つのコマンドで完了することができるので、あなたはRedisのものを更新することに関連している矛盾している更新とどんな十字シャード複雑さのどんな懸念でも取り除きます.

    資源

  • Redisオームのためのチュートリアルが、ありますdeveloper.redis.com
  • あなたがRedisオームのために問題またはPRを開くことを望むならばGitHub
  • Redisの詳細についてはredis.io
  • REDISJSONの詳細については、REDISの検索機能を有効にするモジュールredisjson.io