ElasticSearch NEST 7.x 将项目附加到现有文档对象数组 属性

ElasticSearch NEST 7.x append item to existing document object array property

我正在寻找一种将项目附加到索引文档中现有对象列表的方法。

我有这样定义的对象。

public class ElasticIndividual 
    {
        public string? Id{get; set;}        
        public IReadOnlyList<Participation>? ParticipationList{get; set;}
    }

我想用新项目更新 ParticipationList。我知道我可以用添加了项目的列表覆盖这个列表,但我没有完整的列表,我不想执行搜索来获取这个列表。

是否可以附加项目而不是覆盖?

Script update 会帮你解决这个问题。

var updateResponse = await elasticClient.UpdateAsync<EsDocument>(
    "1",
    u => u.Script(s => s
        .Source("ctx._source.participations.add(params.item)")
        .Params(objects => objects.Add("item", new Participation {Name = "new item"}))));

示例应用程序下方

class Program
{
    static async Task Main(string[] args)
    {
        string indexName = "my_index";
        var connectionSettings = new ConnectionSettings(new Uri("http://localhost:9200"));
        connectionSettings.DefaultIndex(indexName);
        var elasticClient = new ElasticClient(connectionSettings);

        await elasticClient.Indices.DeleteAsync(indexName);
        var indexResponse = await elasticClient.Indices.CreateAsync(indexName);

        var indexDocumentAsync = await elasticClient
            .IndexDocumentAsync(new EsDocument {Id = "1", Participations = new List<Participation> { new Participation { Name = "test" }}});

        var updateResponse = await elasticClient.UpdateAsync<EsDocument>(
            "1",
            u => u.Script(s => s
                .Source("ctx._source.participations.add(params.item)")
                .Params(objects => objects.Add("item", new Participation {Name = "new item"}))));
    }

    class EsDocument
    {
        public string Id { get; set; }
        public List<Participation> Participations { get; set; } = new List<Participation>();
    }

    class Participation
    {
        public string Name { get; set; }
    }
}

更新

多个文档的批量操作可以像下面这样构造

var bulkResponse = await elasticClient.BulkAsync(b => b
    .Update<EsDocument>(u => u
        .Id("1")
        .Script(_ => new InlineScriptDescriptor("ctx._source.participations.add(params.item)")
            .Params(objects => objects.Add("item", new Participation {Name = "new item"}))))
    .Update<EsDocument>(u => u
        .Id("2")
        .Script(_ => new InlineScriptDescriptor("ctx._source.participations.add(params.item)")
            .Params(objects => objects.Add("item", new Participation {Name = "new item"}))))
);