Elastic.Clients.Elasticsearch 8.1.0执行SQL查询无返回行的问题咨询
问题解决:.NET Elasticsearch客户端SQL查询仅返回列和游标无行数据
原因分析
这不是客户端支持不完善,而是Elasticsearch SQL API的分页机制导致的:
- Kibana请求中使用了
format=csv,Elasticsearch会自动一次性返回所有查询结果并格式化为CSV; - .NET客户端调用的是原生SQL查询API,当结果集超过默认阈值(或符合分页条件)时,会返回列信息+游标(Cursor),需要通过游标继续获取剩余行数据。
解决方案
方案1:手动处理游标获取全量数据
如果数据量较大,建议通过循环游标分批获取:
var response = await _elasticsearchClient.Sql.QueryAsync(q => q.Query("SELECT * FROM persons")); // 存储所有列和行数据 var columns = response.Columns; var allRows = new List<Dictionary<string, object>>(); // 处理首次返回的行(如果有) if (response.Rows != null) { foreach (var row in response.Rows) { var rowDict = new Dictionary<string, object>(); for (int i = 0; i < columns.Count; i++) { rowDict[columns[i].Name] = row[i]; } allRows.Add(rowDict); } } // 循环使用游标获取剩余数据 while (!string.IsNullOrEmpty(response.Cursor)) { response = await _elasticsearchClient.Sql.QueryAsync(q => q.Cursor(response.Cursor)); if (response.Rows != null) { foreach (var row in response.Rows) { var rowDict = new Dictionary<string, object>(); for (int i = 0; i < columns.Count; i++) { rowDict[columns[i].Name] = row[i]; } allRows.Add(rowDict); } } } // allRows即为完整的查询结果
方案2:设置FetchSize一次性获取数据
如果数据量较小(确定不会超过Elasticsearch的内存限制),可以通过FetchSize指定单次返回的最大行数,直接获取全量数据:
var response = await _elasticsearchClient.Sql.QueryAsync(q => q .Query("SELECT * FROM persons") .FetchSize(10000)); // 根据实际数据量调整大小
当设置的FetchSize大于等于结果集总条数时,响应中会直接返回所有行数据,不会生成游标。
内容的提问来源于stack exchange,提问作者Felix
相关产品推荐
相关产品推荐

