簡體   English   中英

如何從 ElasticSearch 獲取分數列的總和

[英]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 進行了幾次實驗后,我得出了以下結論:

  1. CData ODBC 驅動程序知道不可能在_score上進行聚合,並且不允許用戶這樣做
  2. 它實際通過_score計算聚合的_score很可能是一個錯誤,不是由 ElasticSearch 執行,而是由驅動程序執行。

簡而言之,不要將_score用於任何GROUP BY ,這是 ElasticSearch 專門用於相關性排序的特殊功能。

一點介紹

正如我在對問題的評論中已經提到的, _score中的 _score 是衡量文檔與給定查詢的相關程度的指標(請參閱文檔):

每個文檔的相關性分數由一個稱為 _score 的正浮點數表示。 _score 越高,文檔越相關。

該字段不是文檔的一部分,而是為每個查詢和每個文檔計算的。 在 ElasticSearch 中_score用於排序 但是, _score 並不總是計算的,例如當需要對現有字段進行排序時:

_score 未計算,因為它沒有用於排序。

由於此字段是即時計算的,因此無法創建有效的聚合,因此 ElasticSearch 不允許直接這樣做。 但是,這仍然可以通過在聚合中使用腳本來實現。

CData ODBC 驅動程序知道 _score 字段

CData ODBC 驅動程序知道_score字段

選擇_CORE列時,將通過發出查詢上下文請求請求評分,該請求評分搜索結果的質量。 默認情況下,結果根據計算出的 _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進行聚合,並且這里的“工作”案例可能是一個錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM