带版本控制的Elasticsearch更新 - NEST / C#

时间:2017-05-05 23:04:51

标签: c# elasticsearch nest

我希望实现弹性搜索版本控制功能,以使用NEST库和C#更新记录。我实际上是想创建一个帮助器,它执行以下操作:

  1. 阅读现有记录。
  2. 更改记录。
  3. 使用版本功能更新文档。
  4. 我做了一些研究,但没有找到我要找的信息。有人能指出一些代码示例,实现或测试吗?

1 个答案:

答案 0 :(得分:1)

我使用以下类,其中包括版本控制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);
    }
}

负责处理Retry并重试更新的version_conflict_engine_exception方法。 Update方法使用lambda来处理或更新实体,以处理从索引中检索的实体。以下是使用此类

的示例
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;
});