Please explain how to perform a bulk update with partials using UpdateMany

I am really surprised by the lack of documentation for the NEST client.

I am using NEST 6.6.0. I have an array of partial documents (anonymous objects) -- each includes an id field and the fields that I want to update.

Please show me an example of how to do this. I've seen an example where the you have to pass an IEnumerable< T > instead of IEnumerable< TPartial >, but that doesn't make sense. I have a bunch of partial documents that include the ids already. Is there a way to do this?

The IEnumerable<T> passed to UpdateMany<T> can be a collection of partial objects, you just need to be aware that index name and type name would be inferred from T in this case, unless explicitly provided.

I think you want something like the following

private static void Main()
{
    var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
    var settings = new ConnectionSettings(pool);
    var client = new ElasticClient(settings);

	var partials = new object[] 
	{
		new { id = 1, title = "foo" },
		new { id = 2, body = "bar" },
		new { id = 3, title = "baz" },
	};
	
	var bulkResponse = client.Bulk(b => b
		.Index("index_name") // explicitly provide index name
		.Type("doc_type") // explicitly provide doc type
		.UpdateMany(partials, (bu, d) => bu.Doc(d))
	);
}

This generates the following request

POST http://localhost:9200/index_name/doc_type/_bulk
{"update":{"_id":"1"}}
{"doc":{"id":1,"title":"foo"}}
{"update":{"_id":"2"}}
{"doc":{"id":2,"body":"bar"}}
{"update":{"_id":"3"}}
{"doc":{"id":3,"title":"baz"}}

That mostly works for me. Is there a way to somehow specify a property in the anonymous object to be an id so that I don't have to use the property name "id"?

Not for an anonymous type. The id property is picked up by NEST conventions, but if you wanted to have another property inferred to be the id of the document, you would need to create a POCO for it

[ElasticsearchType(IdProperty = nameof(MyId))]
public class PartialDoc
{
	public int MyId { get; set; }

	public string Title { get; set; }
	
	public string Body { get; set; }
}

var partials = new PartialDoc[]
{
	new PartialDoc{ MyId = 1, Title = "foo" },
	new PartialDoc{ MyId = 2, Body = "bar" },
	new PartialDoc{ MyId = 3, Title = "baz" },
};

var bulkResponse = client.Bulk(b => b
	.Index("index_name") // explicitly provide index name
	.Type("doc_type") // explicitly provide doc type
	.UpdateMany(partials, (bu, d) => bu.Doc(d))
);

which would yield

POST http://localhost:9200/index_name/doc_type/_bulk?pretty=true 
{"update":{"_id":"1"}}
{"doc":{"myId":1,"title":"foo"}}
{"update":{"_id":"2"}}
{"doc":{"myId":2,"body":"bar"}}
{"update":{"_id":"3"}}
{"doc":{"myId":3,"title":"baz"}}

You can also configure the property to use for the document ID on ConnectionSettings.

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.