亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

將文檔屬性設置為 null 并在更新時從數據庫中刪除字段

將文檔屬性設置為 null 并在更新時從數據庫中刪除字段

C#
楊__羊羊 2023-07-22 18:40:07
我有下面的 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 字段以從文檔中刪除。
查看完整描述

1 回答

?
HUH函數

TA貢獻1836條經驗 獲得超4個贊

我最終創建了以下方法。


public async Task<Result> UpdateAsync(

    T document, 

    string indexName = null, 

    string typeName = null,

    Refresh? refresh = null, 

    CancellationToken cancellationToken = default)

{

    Guard.Argument(document, nameof(document)).NotNull();


    await RemoveNullFieldsFromDocumentAsync(document, document.Id, indexName, typeName, cancellationToken);


    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);

}


public async Task<Result> UpdateAsync(

    string id, 

    object partialDocument, 

    string indexName = null, 

    string typeName = null,

    Refresh? refresh = null, 

    CancellationToken cancellationToken = default)

{

    Guard.Argument(partialDocument, nameof(partialDocument)).NotNull();

    Guard.Argument(id, nameof(id)).NotNull().NotEmpty().NotWhiteSpace();


    await RemoveNullFieldsFromDocumentAsync(partialDocument, id, indexName, typeName, cancellationToken);


    var response = await Client.UpdateAsync<T, object>(

        id, 

        u => u.Doc(partialDocument)

            .Index(indexName ?? DocumentMappings.IndexStrategy)

            .Type(typeName ?? DocumentMappings.TypeName)

            .Refresh(refresh), 

        cancellationToken);


    var errorMessage = response.LogResponseIfError(_logger);


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

}


private async Task<Result> RemoveNullFieldsFromDocumentAsync(

    object document,

    string documentId,

    string indexName = null, 

    string typeName = null,

    CancellationToken cancellationToken = default)

{

    var result = Result.Ok();

    var allNullProperties = GetNullPropertyValueNames(document);

    if (allNullProperties.AnyAndNotNull())

    {

        var script = allNullProperties.Select(p => $"ctx._source.remove('{p}')").Aggregate((p1, p2) => $"{p1}; {p2};");

        result = await UpdateByQueryIdAsync(

                                        documentId, 

                                        script,

                                        indexName,

                                        typeName,

                                        cancellationToken: cancellationToken);

    }


    return result;

}


private static IReadOnlyList<string> GetNullPropertyValueNames(object document)

{

    var allPublicProperties =  document.GetType().GetProperties().ToList();


    var allObjects = allPublicProperties.Where(pi => pi.PropertyType.IsClass).ToList();


    var allNames = new List<string>();


    foreach (var propertyInfo in allObjects)

    {

        if (propertyInfo.PropertyType == typeof(string))

        {

            var isNullOrEmpty = ((string) propertyInfo.GetValue(document)).IsNullOrEmpty();

            if (isNullOrEmpty)

            {

                allNames.Add(propertyInfo.Name.ToCamelCase());

            }

        }

        else if (propertyInfo.PropertyType.IsClass)

        {

            if (propertyInfo.GetValue(document).IsNotNull())

            {

                var namesWithobjectName = GetNullPropertyValueNames(propertyInfo.GetValue(document))

                    .Select(p => $"{propertyInfo.PropertyType.Name.ToCamelCase()}.{p.ToCamelCase()}");

                allNames.AddRange(namesWithobjectName);

            }

        }

    }


    return allNames;

}


public async Task<Result> UpdateByQueryIdAsync(

    string documentId,

    string script,

    string indexName = null, 

    string typeName = null, 

    bool waitForCompletion= false,

    CancellationToken cancellationToken = default)

{

    Guard.Argument(documentId, nameof(documentId)).NotNull().NotEmpty().NotWhiteSpace();

    Guard.Argument(script, nameof(script)).NotNull().NotEmpty().NotWhiteSpace();


    var response = await Client.UpdateByQueryAsync<T>(

        u => u.Query(q => q.Ids(i => i.Values(documentId)))

                .Conflicts(Conflicts.Proceed)

                .Script(s => s.Source(script))

                .Refresh()

                .WaitForCompletion(waitForCompletion)

                .Index(indexName ?? DocumentMappings.IndexStrategy)

                .Type(typeName ?? DocumentMappings.TypeName), 

        cancellationToken);


    var errorMessage = response.LogResponseIfError(_logger);


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

}



查看完整回答
反對 回復 2023-07-22
  • 1 回答
  • 0 關注
  • 123 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號