Using sql query with parameters in dotnet client

When using the .net nuget package Elastic.Clients.Elasticsearch (version 8.1.3) to connect to an elastic cloud instance (running elastic v8.7.1), I am trying to use the sql query but I am struggling with the Params property on the QueryRequest. This property is a IDictionary<string, object> but if it is set, then Elasticsearch always seems to return an error.

I have found documentation on using sql syntax with the nuget package hard to find. The documentation here Introduction | Elasticsearch .NET Client [8.1] | Elastic doesn't mention the sql namespace at all.

The following code demonstrates the issue:

using Elastic.Clients.Elasticsearch;
using Elastic.Clients.Elasticsearch.Sql;
using Elastic.Transport;

const string CloudId = "MyCloudId";
const string ApiKey = "MyApiKey";

var client = new ElasticsearchClient(CloudId, new ApiKey(ApiKey));

// create simple sql query needing no parameters
var request1 = new QueryRequest
{
    Query = "SELECT machineName,username,message, COUNT(1) AS errorCount FROM debug_errors GROUP BY machineName, username,message ORDER BY errorCount DESC",
    FetchSize = 100,
};

// this request works fine
var response1 = client.Sql.Query(request1);
Console.WriteLine(response1.DebugInformation);

// attempt to create a dictionary of parameters - no idea what the key should be as the rest client just wants an array
var parameters = new Dictionary<string, object>
{
    { "0",  DateTime.Now.Date },
};

var request2 = new QueryRequest
{
    Query = "SELECT machineName,username,message, COUNT(1) AS errorCount FROM debug_errors WHERE dateAdded=? GROUP BY machineName, username,message ORDER BY errorCount DESC",
    Params = parameters,
    FetchSize = 100,
};

/* this request fails with:
Invalid Elasticsearch response built from a unsuccessful (400) low level call on POST: /_sql
 Exception: Request failed to execute. Call: Status code 400 from: POST /_sql. ServerError: Type: x_content_parse_exception Reason: "[1:207] [sql/query] params doesn't support values of type: START_OBJECT"
*/
var response2 = client.Sql.Query(request2);
Console.WriteLine(response2.DebugInformation);

// create request requiring no parameters but provide an empty dictionary
var request3 = new QueryRequest
{
    Query = "SELECT machineName,username,message, COUNT(1) AS errorCount FROM debug_errors GROUP BY machineName, username,message ORDER BY errorCount DESC",
    FetchSize = 100,
    Params = new Dictionary<string, object>(),
};

// this request also fails with an empty dictionary
var response3 = client.Sql.Query(request3);
Console.WriteLine(response3.DebugInformation);

If I use postman, I can get the query to work with the _sql endpoint:

{ 
    "fetch_size": 100, 
    "query": "SELECT machineName,username,message, COUNT(1) AS errorCount FROM debug_errors WHERE dateAdded=? GROUP BY machineName, username,message ORDER BY errorCount DESC", 
    "params": [ "2023-07-14" ] 
}

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