2017-05-05 13 views
0

Elastic search versioning機能を実装して、NESTライブラリとC#を使用してレコードを更新しようとしています。私は実際に以下を行うヘルパーを作成しようとしています:バージョン管理 - NEST/C#

  1. 既存のレコードを読みます。
  2. レコードを変更します。
  3. バージョン機能を使用してドキュメントを更新します。

私は私の研究の一部を行い、私が探している情報を見つけませんでした。誰も私にいくつかのコード例、実装またはテストを教えてもらえますか?

+2

を使用しての例です。http://forloop.co.uk/blog/optimistic-concurrency-with -elasticsearch-and-nestはElasticsearch 1.xとNEST 1.xを使用していますが、基本的には2.xと5.xと同じです。 –

+0

これは機能の実装方法に関する明確なコンテキストを示しています。ありがとう、トン! –

+0

こんにちは@RussCam、あなたの記事では、ElasticsearchServerExceptionオブジェクトを使用して、再試行を捕まえて処理することに気付きました。何らかの理由で私は自分のコードでこのオブジェクトにアクセスできません。私はElasticsearchClientExceptionを参照してください。サーバー例外にアクセスする方法を指摘できますか? –

答えて

1

私はversion_conflict_engine_exceptionと再試行の更新処理を担当Retry方法Update

public class SampleElasticClient 
{ 
    private const string VERSION_CONFLICT_ERROR = "version_conflict_engine_exception"; 

    protected readonly string IndexName; 

    protected readonly ElasticClient Client; 

    public SampleElasticClient(Uri uri, string indexName) 
    { 
     Client = new ElasticClient(new ConnectionSettings(uri).DefaultIndex(indexName)); 
     IndexName = indexName; 
    } 

    public IGetResponse<T> Get<T>(Id id) where T : class 
    { 
     var request = new GetRequest<T>(IndexName, typeof(T), id); 
     var response = Client.Get<T>(request); 
     EnsureSuccessResponse(response); 
     return response; 
    } 

    public void Update<T>(Id id, Func<T, T> update, int retriesCount = 10) where T : class 
    { 
     Retry(() => 
     { 
      var getResponse = Get<T>(id); 
      var item = update(getResponse.Source); 
      return Client.Index(item, index => getResponse.Found 
       ? index.Version(getResponse.Version) 
       : index.OpType(OpType.Create)); 
     }, retriesCount); 
    } 

    protected void EnsureSuccessResponse(IResponse response) 
    { 
     if (!response.IsValid && response.ApiCall.HttpStatusCode != 404) 
     { 
      var errorMessage = response.ServerError != null 
       ? $"ElasticSearch error: {response.ServerError.Error}\r\n" + 
           $"Http status: {response.ServerError.Status}" 
       : $"ElasticSearch error. {response.DebugInformation}"; 
      throw new Exception(errorMessage); 
     } 
    } 

    protected void Retry(Func<IResponse> execute, int retriesCount) 
    { 
     var numberOfRetry = 0; 
     do 
     { 
      var response = execute(); 
      if (response.ServerError?.Error.Type != VERSION_CONFLICT_ERROR || ++numberOfRetry == retriesCount) 
      { 
       EnsureSuccessResponse(response); 
       return; 
      } 
     } while (true); 
    } 
} 

をバージョニング含ん以下のクラスを使用します。 Updateメソッドentherは、インデックスから取得したエンティティを処理するためにラムダを使用してエンティティを挿入または更新します。ここで私は、ESとNESTとの楽観的同時実行制御について数年前にブログ記事を書いた、このクラスに

var client = new SampleElasticClient(new Uri("http://localhost:9200"), indexName); 
var id = 123; 
client.Update<Sample>(id, entity => 
{ 
    if (entity == null) 
     entity = new Sample { Id = id }; // Or any other action for new entity 

    entity.MyField = "new value"; 
    return entity; 
}); 
関連する問題