elastic / elasticsearch-net

This strongly-typed, client library enables working with Elasticsearch. It is the official client maintained and supported by Elastic.
https://www.elastic.co/guide/en/elasticsearch/client/net-api/current/index.html
Apache License 2.0
3.58k stars 1.15k forks source link

OriginalException: Elasticsearch.Net.ElasticsearchClientException: Request failed to execute when get sql result as csv type #6410

Closed azadmt closed 2 years ago

azadmt commented 2 years ago

NEST/Elasticsearch.Net version:7.17.1

Elasticsearch version:8+

when I want get Result as csv format whith folowing code:

       var connectionSettings = new ConnectionSettings(connectionPool)
                .DisableDirectStreaming()
                .DefaultIndex(defaultIndex)
                .BasicAuthentication("****", "****");

        var response = _elasticClient.Sql.Query(p => p.Format("csv").Query($"SELECT * FROM INDEX_NAME"));

       OR

         var response = _elasticClient.LowLevel.Sql.Query<SearchResponse<string>>(PostData.Serializable(new
                {
                    query = "SELECT * FROM INDEX_NAME"
                }),new Elasticsearch.Net.Specification.SqlApi.QuerySqlRequestParameters { Format="csv"});

I get this exception:

_Invalid NEST response built from a unsuccessful (200) low level call on POST: /_sql?format=csv

Audit trail of this API call:

stevejgordon commented 2 years ago

Hi, @azadmt.

The high-level client is designed to work with JSON responses which are deserialised to strong types.

If you need to work with raw CSV data, this can be achieved but must use the low-level client. Your code above is pretty close to what you require.

var config = new RequestConfiguration 
{ 
    ContentType = "application/json",
    Accept = "text/csv; charset=utf-8;"
};

var requestParameters = new QuerySqlRequestParameters { Format = "csv", RequestConfiguration = config };

var response = client.LowLevel.Sql.Query<StringResponse>(PostData.Serializable(new
{
    query = "SELECT * FROM INDEX_NAME"
}), requestParameters);

var csvData = response.Body;

The main difference here is the response type for the generic argument. You must use either StringResponse or BytesResponse here. This will provide access to the raw body on response.Body.

Note that to use 7.17 with the 8.x server you should also enable API version headers. Due to the use of CSV as the response format, these need to be manually provided using RequestConfiguration. There are some inconsistencies with using API versioning with the SQL query API which I need to discuss with the server team, but the above should work for now to provide a valid response. This ignore API versioning for this specific request so that the client does not incorrectly determine the response is invalid due to the response Content-Type not matching the expected value.

stevejgordon commented 2 years ago

Closing as no action. Non-JSON formats are not a supported scenario for the client.