[英]How to get sum of score column from ElasticSearch
我是 Elasticsearch 的新手。 我嘗試使用 CData Elasticsearch ODBC 驅動程序從 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 函數。
但下面的查詢返回結果:
“選擇 _id, sum(_score) from ordersdetails group by _id”
任何人都知道,為什么在嘗試獲取單個列的結果時出現異常?
如果您知道解決方案,請與我分享。
在對pyodbc
和 ElasticSearch 進行了幾次實驗后,我得出了以下結論:
_score
上進行聚合,並且不允許用戶這樣做_score
計算聚合的_score
很可能是一個錯誤,不是由 ElasticSearch 執行,而是由驅動程序執行。 簡而言之,不要將_score
用於任何GROUP BY
,這是 ElasticSearch 專門用於相關性排序的特殊功能。
正如我在對問題的評論中已經提到的, _score
中的 _score 是衡量文檔與給定查詢的相關程度的指標(請參閱文檔):
每個文檔的相關性分數由一個稱為 _score 的正浮點數表示。 _score 越高,文檔越相關。
該字段不是文檔的一部分,而是為每個查詢和每個文檔計算的。 在 ElasticSearch 中_score
用於排序。 但是, _score
並不總是計算的,例如當需要對現有字段進行排序時:
_score 未計算,因為它沒有用於排序。
由於此字段是即時計算的,因此無法創建有效的聚合,因此 ElasticSearch 不允許直接這樣做。 但是,這仍然可以通過在聚合中使用腳本來實現。
CData ODBC 驅動程序知道_score
字段:
選擇_CORE列時,將通過發出查詢上下文請求請求評分,該請求評分搜索結果的質量。 默認情況下,結果根據計算出的 _score 以降序返回。 可以指定 ORDER BY 子句來更改返回結果的順序。
當 _score 列未被選中時,將發送過濾上下文,在這種情況下 Elasticsearch 將不會計算分數。 除非明確指定 ORDER BY 子句,否則這些查詢的結果將以任意順序返回。
基本上,這意味着通過在查詢中明確提及_score
將使 ODBC 返回此類字段(默認情況下可能存在)。
我安裝了 pyodbc 並在我的本地主機上設置了 ElasticSearch 5.4。 我調整了 ES 以記錄它收到的所有查詢。
一開始我復現了第一種情況:
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}
接下來我進行了第二個查詢:
cursor.execute("SELECT _id, sum(_score) FROM my_index.my_type GROUP BY _id")
執行無一例外,但導致此 ES 查詢:
{"from":0,"size":10000,"_source":{"includes":["_id","_score"],"excludes":[]}}
然后我嘗試使用不存在的字段來模擬庫:
cursor.execute("SELECT sum(score42) FROM simple_index.simple_type")
在這種情況下,異常是不同的:
[HY000] 'score42' is not a valid column.
盡管發送到 ES 的查詢與第一種情況相同。
然后我試圖找出庫是如何發送聚合請求的:
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
進行聚合,並且這里的“工作”案例可能是一個錯誤。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.