将文档属性设置为 null 并在更新时从数据库中删除字段

我有下面的 C# 类。


public class ElasticSearchDocument

{

    public string Id { get; set; } = Guid.NewGuid().ToString();


    public string Description { get; set; }

}

我还在我的文档中使用模板,下面的模板用于演示测试。


{

  "version": 2,

  "index_patterns": "documents-test*",

  "order": 2,

  "aliases": {

    "docs-test": {}

  },

  "settings": {

    "number_of_shards": 1

  },

  "mappings": {

    "_doc": {

      "dynamic": "strict",

      "properties": {

        "id": {

          "type": "keyword"

        },

        "description": {

          "enabled": false

        }

      }

    }

  }

}

我将该Description属性设置为 ahas value并为其建立索引。下面是数据库中的示例。


{

  "_index": "documents-test-2019-07-2-2",

  "_type": "_doc",

  "_id": "55096ff7-5072-4ded-b6a3-94b8e155c9d0",

  "_score": 1,

  "_source": {

    "id": "55096ff7-5072-4ded-b6a3-94b8e155c9d0",

    "description": "has value"

  }

}

查询文档,将Description属性设置为null并使用以下 NESTIElasticClient.UpdateAsync方法更新文档。


public async Task<Result> UpdateAsync(

 T document,

 string indexName = null,

 string typeName = null,

 Refresh ? refresh = null,

 CancellationToken cancellationToken =

 default) {


 var response = await Client.UpdateAsync<T,

  object>(

   document.Id,

   u => u.Doc(document)

   .Index(indexName ? ? DocumentMappings.IndexStrategy)

   .Type(typeName ? ? DocumentMappings.TypeName)

   .Refresh(refresh),

   cancellationToken);


 var errorMessage = response.LogResponseIfError(_logger);


 return errorMessage.IsNullOrEmpty() ? Result.Ok() : Result.Fail(errorMessage);

}

问题是更新命令后,文档未更改,字段的description值为has value。


我认为最合适的解决方案是将 C# 类Description属性设置为 null 并更新 Elastic Search 字段以从文档中删除。

杨__羊羊
浏览 85回答 1
1回答

HUH函数

我最终创建了以下方法。public async Task<Result> UpdateAsync(&nbsp; &nbsp; T document,&nbsp;&nbsp; &nbsp; string indexName = null,&nbsp;&nbsp; &nbsp; string typeName = null,&nbsp; &nbsp; Refresh? refresh = null,&nbsp;&nbsp; &nbsp; CancellationToken cancellationToken = default){&nbsp; &nbsp; Guard.Argument(document, nameof(document)).NotNull();&nbsp; &nbsp; await RemoveNullFieldsFromDocumentAsync(document, document.Id, indexName, typeName, cancellationToken);&nbsp; &nbsp; var response = await Client.UpdateAsync<T, object>(&nbsp; &nbsp; &nbsp; &nbsp; document.Id,&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; u => u.Doc(document)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .Index(indexName ?? DocumentMappings.IndexStrategy)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .Type(typeName ?? DocumentMappings.TypeName)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .Refresh(refresh),&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; cancellationToken);&nbsp; &nbsp; var errorMessage = response.LogResponseIfError(_logger);&nbsp; &nbsp; return errorMessage.IsNullOrEmpty() ? Result.Ok() : Result.Fail(errorMessage);}public async Task<Result> UpdateAsync(&nbsp; &nbsp; string id,&nbsp;&nbsp; &nbsp; object partialDocument,&nbsp;&nbsp; &nbsp; string indexName = null,&nbsp;&nbsp; &nbsp; string typeName = null,&nbsp; &nbsp; Refresh? refresh = null,&nbsp;&nbsp; &nbsp; CancellationToken cancellationToken = default){&nbsp; &nbsp; Guard.Argument(partialDocument, nameof(partialDocument)).NotNull();&nbsp; &nbsp; Guard.Argument(id, nameof(id)).NotNull().NotEmpty().NotWhiteSpace();&nbsp; &nbsp; await RemoveNullFieldsFromDocumentAsync(partialDocument, id, indexName, typeName, cancellationToken);&nbsp; &nbsp; var response = await Client.UpdateAsync<T, object>(&nbsp; &nbsp; &nbsp; &nbsp; id,&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; u => u.Doc(partialDocument)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .Index(indexName ?? DocumentMappings.IndexStrategy)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .Type(typeName ?? DocumentMappings.TypeName)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .Refresh(refresh),&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; cancellationToken);&nbsp; &nbsp; var errorMessage = response.LogResponseIfError(_logger);&nbsp; &nbsp; return errorMessage.IsNullOrEmpty() ? Result.Ok() : Result.Fail(errorMessage);}private async Task<Result> RemoveNullFieldsFromDocumentAsync(&nbsp; &nbsp; object document,&nbsp; &nbsp; string documentId,&nbsp; &nbsp; string indexName = null,&nbsp;&nbsp; &nbsp; string typeName = null,&nbsp; &nbsp; CancellationToken cancellationToken = default){&nbsp; &nbsp; var result = Result.Ok();&nbsp; &nbsp; var allNullProperties = GetNullPropertyValueNames(document);&nbsp; &nbsp; if (allNullProperties.AnyAndNotNull())&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; var script = allNullProperties.Select(p => $"ctx._source.remove('{p}')").Aggregate((p1, p2) => $"{p1}; {p2};");&nbsp; &nbsp; &nbsp; &nbsp; result = await UpdateByQueryIdAsync(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; documentId,&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; script,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; indexName,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; typeName,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cancellationToken: cancellationToken);&nbsp; &nbsp; }&nbsp; &nbsp; return result;}private static IReadOnlyList<string> GetNullPropertyValueNames(object document){&nbsp; &nbsp; var allPublicProperties =&nbsp; document.GetType().GetProperties().ToList();&nbsp; &nbsp; var allObjects = allPublicProperties.Where(pi => pi.PropertyType.IsClass).ToList();&nbsp; &nbsp; var allNames = new List<string>();&nbsp; &nbsp; foreach (var propertyInfo in allObjects)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; if (propertyInfo.PropertyType == typeof(string))&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var isNullOrEmpty = ((string) propertyInfo.GetValue(document)).IsNullOrEmpty();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (isNullOrEmpty)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; allNames.Add(propertyInfo.Name.ToCamelCase());&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; else if (propertyInfo.PropertyType.IsClass)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (propertyInfo.GetValue(document).IsNotNull())&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var namesWithobjectName = GetNullPropertyValueNames(propertyInfo.GetValue(document))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .Select(p => $"{propertyInfo.PropertyType.Name.ToCamelCase()}.{p.ToCamelCase()}");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; allNames.AddRange(namesWithobjectName);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; return allNames;}public async Task<Result> UpdateByQueryIdAsync(&nbsp; &nbsp; string documentId,&nbsp; &nbsp; string script,&nbsp; &nbsp; string indexName = null,&nbsp;&nbsp; &nbsp; string typeName = null,&nbsp;&nbsp; &nbsp; bool waitForCompletion= false,&nbsp; &nbsp; CancellationToken cancellationToken = default){&nbsp; &nbsp; Guard.Argument(documentId, nameof(documentId)).NotNull().NotEmpty().NotWhiteSpace();&nbsp; &nbsp; Guard.Argument(script, nameof(script)).NotNull().NotEmpty().NotWhiteSpace();&nbsp; &nbsp; var response = await Client.UpdateByQueryAsync<T>(&nbsp; &nbsp; &nbsp; &nbsp; u => u.Query(q => q.Ids(i => i.Values(documentId)))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .Conflicts(Conflicts.Proceed)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .Script(s => s.Source(script))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .Refresh()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .WaitForCompletion(waitForCompletion)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .Index(indexName ?? DocumentMappings.IndexStrategy)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .Type(typeName ?? DocumentMappings.TypeName),&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; cancellationToken);&nbsp; &nbsp; var errorMessage = response.LogResponseIfError(_logger);&nbsp; &nbsp; return errorMessage.IsNullOrEmpty() ? Result.Ok() : Result.Fail(errorMessage);}
打开App,查看更多内容
随时随地看视频慕课网APP