如何从ElasticSearch中获取分数总和列



我是Elasticsearch的新手。我试图使用CDataElasticsearchODBC驱动程序从ES中获得结果。有可能得到分数总和字段吗?

我的代码:

OdbcConnection connection = new OdbcConnection("Driver={CData ODBC Driver for Elasticsearch};server=localhost");
connection.Open();
string query = "select sum(_score) from ordersdetails";
OdbcCommand odbcCommand = new OdbcCommand(query, connection);
OdbcDataReader dataReader = odbcCommand.ExecuteReader();
DataTable dataTable = new DataTable();
dataTable.Load(dataReader);
connection.Close();

我遇到了以下异常

System.Data.Odbc.OdbcException:"ERROR[HY000]"_score"列不适用于sum函数。">

但是下面的查询返回结果:

"select _id,sum(_score)from orders tails group by _id">

有人知道吗,为什么我在试图获得单个列的结果时出现异常

如果你知道解决方案,请与我分享。

在用pyodbc和ElasticSearch做了几个实验后,我得出了以下结论:

  1. CData ODBC驱动程序知道不可能在_score上进行聚合,并且不允许用户这样做
  2. 它实际通过_score计算聚合的行为很可能是一个错误,它不是由ElasticSearch执行的,而是由驱动程序执行的

简而言之,不要将_score用于任何GROUP BY,这是ElasticSearch专门用于相关性排序的一个特殊功能。

介绍一下

正如我在对该问题的评论中所提到的,ElasticSearch中的_score是衡量文档如何与给定查询相关的指标(请参阅文档):

每个文档的相关性得分由正数表示称为_score的浮点数。_score越高更相关的文件。

此字段不是文档的一部分,是为每个查询和每个文档计算的。在ElasticSearch中,_score用于排序。然而,并不总是计算_score,例如,当需要对现有字段进行排序时:

_score未计算,因为它未用于排序。

由于此字段是动态计算的,因此不可能创建有效的聚合,因此ElasticSearch不允许直接进行此操作。但是,这仍然可以通过在聚合中使用脚本来实现。

CData ODBC驱动程序知道_score字段

CData ODBC驱动程序知道_score字段:

选择_score列时,将由发出查询上下文请求,该请求对搜索结果。默认情况下,结果按降序返回基于计算的_ score。ORDER BY子句可以指定为更改返回结果的顺序。

当_score列未被选择时,将发送过滤器上下文,在这种情况下,Elasticsearch将不会计算分数。的结果除非order BY子句是明确指定的。

基本上,这意味着通过在查询中显式提及_score,ODBC将返回这样的字段(默认情况下可能存在)。

实验

我在本地主机上安装了pyodbc并设置了ElasticSearch 5.4。我调整了ES以记录它收到的所有查询。

1

起初,我复制了第一个案例:

cursor.execute("SELECT sum(_score) FROM my_index.my_type")

并收到此异常:

[HY000] The '_score' column is not applicable to the sum function.

在ES的日志中,我捕捉到了这个查询:

{"from":0,"size":100}

2

接下来我进行了第二个查询:

cursor.execute("SELECT _id, sum(_score) FROM my_index.my_type GROUP BY _id")

执行时没有异常,但导致了这个ES查询:

{"from":0,"size":10000,"_source":{"includes":["_id","_score"],"excludes":[]}}

3

然后我尝试用不存在的字段来模拟库:

cursor.execute("SELECT sum(score42) FROM simple_index.simple_type")

在这种情况下,例外情况不同:

[HY000] 'score42' is not a valid column.

尽管发送给ES的查询与第一种情况相同。

4

然后我试着找出库是如何发送聚合请求的:

cursor.execute("SELECT sum(likes) FROM simple_index.simple_type GROUP BY likes")

事实上,它确实使用了ES聚合:

{
"from": 0,
"size": 0,
"aggregations": {
"likes": {
"terms": {
"field": "likes",
"size": 2147483647,
"min_doc_count": 1,
"shard_min_doc_count": 0,
"show_term_doc_count_error": false,
"order": [
{
"_count": "desc"
},
{
"_term": "asc"
}
]
},
"aggregations": {
"sum_likes": {
"sum": {
"field": "likes"
}
}
}
}
}
}

结论

事实上,该库能够将_score识别为一个特殊的关键字,也因为它在请求sum(_score)时没有尝试生成ES聚合,我认为它通常不允许在_score上进行聚合,这里的"工作"情况可能是一个错误。

相关内容

  • 没有找到相关文章

最新更新