2

I'm looking for a way to append item to existing object list in index document.

I have object defined like this.

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

I would like to update ParticipationList with new item. I know that i can override this list with list with added item but i don't have whole list and i don't want to perform search to get this list.

Is it possible to append item instead override?

1 Answer 1

4

Script update will help you with this.

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

Below example app

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

Update

Bulk operation for multiple docs can be constructed like below

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"}))))
);
Sign up to request clarification or add additional context in comments.

2 Comments

I didn't added that i'm trying to do it using _elastic.Bulk(). Does there is possibility to compose BulkDescriptor to do suche update?
Yes, that's still possible, check my update.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.