elastic/elasticsearch-net

Unable to extract documents from MultiGetResponse

Closed this issue · 4 comments

Elastic.Clients.Elasticsearch version: 8.15.4

Hi,

Inside the MultiGetResponse the elastic documents are wrapped by a MultiGetResponseItem, but this model doesn't expose any retrieval methods. What is the intended method of extracting the elastic documents from this response? Any guidance or documentation to look over would be greatly appreciated. Thanks!

Additional context:

var multiGetResponse = await this.elasticsearchClient.MultiGetAsync<ElasticModel>(c => c
   .Index("my-index")
   .Ids(new Ids(ids))
);

Gives me a MultiGetResponse<ElasticModel> type. Then doing var x = multiGetResponse.Docs.First(); gets me to a MultiGetResponseItem<ElasticModel>, however from here I can't find how to extract the elastic model.

Any help would be great, thanks :)

I'm experiencing the same issue with MultiGetResponseItem in Elastic.Clients.Elasticsearch 8.x. The Docs collection contains private items, making it impossible to access Source directly without reflection.

Is this intentional design? If so, what's the recommended approach?
Could the team expose these properties publicly in a future release?

The current behavior contradicts the principle of least surprise, as most users would expect to access documents directly after a successful query. The workaround significantly impacts code quality.

Thanks

Hi @TSlump @sadeghpour , this seems to be a case where our documentation needs improvement.

Please check the .Match() method on the MultiGetResponseItem. This method exists for all Union types and allows you to fetch the desired variant (in this case either GetResult<TDocument> or MultiGetError) in a safe way.

In the newer versions of the client 8.19-preview and 9.0, all Union types do additionally expose Tag, Value1 and Value2 to allow for built-in pattern matching.

Please let me know if that answer your question.

@flobernd Just wanted to say thanks for your help. I implemented the solution exactly as you suggested:

var products = response.Docs
    .Select(doc => doc.Match(
        result => result.Source,
        _ => null
    ))
    .Where(product => product != null)
    .ToList();

This worked perfectly in our production code (v8.15.9). Really appreciate you taking the time to point us to the correct approach - it's both cleaner and more reliable than our previous reflection workaround. The Match() method is exactly what we needed.

Keep up the great work! 🚀

@flobernd Thank you for your help, I really appreciate your clear response !

@sadeghpour Thank you too for the usage example. This method works for me too :)