

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 寫入表達式查詢
<a name="v9-panels-query-xform-expressions"></a>

****  
本文件主題專為支援 Grafana **9.x 版的 Grafana** 工作區而設計。  
如需支援 Grafana 10.x 版的 Grafana 工作區，請參閱[使用 Grafana 第 10 版](using-grafana-v10.md)。  
如需支援 Grafana 8.x 版的 Grafana 工作區，請參閱 [使用 Grafana 第 8 版](using-grafana-v8.md)。

伺服器端表達式可讓您使用數學和其他操作來操作查詢傳回的資料。運算式會建立新的資料，而且不會操作資料來源傳回的資料。

## 關於表達式
<a name="v9-panels-query-about"></a>

伺服器端表達式可讓您使用數學和其他操作來操作查詢傳回的資料。表達式會建立新的資料，除了一些次要資料重組之外，也不要操作資料來源傳回的資料，讓表達式的資料可接受輸入。

**使用表達式**

表達式主要由 [Grafana 警示](v9-alerts.md)使用。處理是在伺服器端完成，因此表達式可以在沒有瀏覽器工作階段的情況下操作。不過，表達式也可以與後端資料來源和視覺化搭配使用。

**注意**  
表達式不適用於舊版儀表板提醒。

表達式旨在透過啟用來自不同資料來源的查詢合併，或提供資料來源中無法使用的操作來增強資料來源。

**注意**  
如果可能，您應該在資料來源內進行資料處理。將資料從儲存複製到 Grafana 伺服器進行處理效率低，因此表達式以輕量型資料處理為目標。

運算式適用於傳回時間序列或數字資料的資料來源查詢。它們也會在[多維資料](getting-started-grafanaui.md#time-series-dimensions)上運作。例如，傳回多個序列的查詢，其中每個序列都由標籤或標籤識別。

個別表達式會接受一或多個查詢或其他表達式做為輸入，並將資料新增至結果。每個個別表達式或查詢都由變數表示，該變數是稱為其 RefID 的具名識別符 （例如，預設字母 `A`或 `B`)。

若要參考個別表達式的輸出或另一個表達式中的資料來源查詢，此識別符會用作變數。

**表達式的類型**

運算式適用於兩種類型的資料。
+ 時間序列的集合。
+ 數字集合，其中每個數字都是項目。

每個集合會從單一資料來源查詢或表達式傳回，並以 RefID 表示。每個集合都是一組，其中集合中的每個項目都是由儲存為[標籤](getting-started-grafanaui.md#labels)或鍵值對的維度唯一識別。

**資料來源查詢**

伺服器端表達式僅支援後端資料來源的資料來源查詢。通常假設資料標記為時間序列資料。未來，我們打算新增查詢傳回類型 （數字或時間序列） 資料的聲明，以便表達式可以更好地處理錯誤。

資料來源查詢與表達式搭配使用時，是由表達式引擎執行。這樣做時，它會將資料重組為一個時間序列或每個資料影格一個數字。例如，如果使用在資料表檢視中的一個影格上傳回多個序列的資料來源，您可能會注意到使用表達式執行時看起來不同。

目前，使用資料影格時支援的唯一非時間序列格式 （數字） 是您的資料表回應，會傳回沒有時間的資料影格、字串欄和一個數字欄：


| 本機 | 主機 | Avg\$1CPU | 
| --- | --- | --- | 
|  MIA  |  A  |  1  | 
|  NYC  |  B  |  2  | 

上述範例會產生一個可與表達式搭配使用的數字。字串資料欄會變成標籤，數字資料欄會變成對應的值。例如`{"Loc": "MIA", "Host": "A"}`，值為 1 的 。

**操作**

您可以在表達式中使用下列操作：數學、減少和重新取樣。

**Math**

數學適用於時間序列或數字資料的自由格式數學公式。數學運算需要數字和時間序列做為輸入，並將其變更為不同的數字和時間序列。

來自其他查詢或表達式的資料會參考字首為美元符號的 RefID，例如 `$A`。如果變數的名稱中有空格，則可以使用如 的架構語法`${my variable}`。

數值常數可以是十進位 (`2.24`)、八進位 （前導零，如 `072`) 或十六進位 （前導 0x，如 `0x2A`)。也支援指數和符號 （例如 `-0.8e-2`)。

**運算子**

支援算術 (`+`、二進位和單元 `-`、`*`、`/``%`、、指數 `**`)、關聯式 (`<`、`>`、`==``!=`、`>=`、`<=`) 和邏輯 (`||`、 `&&`和單元 `!`) 運算子。

操作與資料的行為方式取決於它是數字還是時間序列資料。

使用二進位操作，例如 `$A + $B`或 `$A || $B`，會根據資料類型，以下列方式套用運算子：
+ 如果 `$A`和 `$B` 都是數字，則操作會在兩個數字之間執行。
+ 如果一個變數是數字，而另一個變數是時間序列，則會執行時間序列中每個點的值與數字之間的操作。
+ 如果 `$A`和 `$B` 都是時間序列資料，則會針對 `$A`和 中存在的每個時間戳記，執行兩個序列中每個值之間的操作`$B`。`Resample` 操作可用來排列時間戳記。

摘要：
+ 數字 OP 數字 = 數字
+ OP 系列數目 = 系列
+ 系列 OP 系列 = 系列

由於表達式使用由單一變數表示的多個序列或數字，因此二進位操作也會在兩個變數之間執行聯集 （聯結）。這是根據與每個個別序列或數字相關聯的識別標籤來完成的。

因此，如果您的數字具有 `{host=web01}`中的標籤`$A`，而另一個數字`$B`具有相同的標籤，則 操作會在每個變數中的這兩個項目之間執行，結果會共用相同的標籤。此聯集的行為規則如下：
+ 沒有標籤的項目將加入任何項目。
+ 如果 `$A`和 `$B` 都只包含一個項目 （一個序列或一個數字），則它們會聯結。
+ 如果標籤是確切的數學，它們將會聯結。
+ 如果標籤是另一個標籤的子集，例如， 中的項目`$A`會加上標籤，`{host=A,dc=MIA}`而 `$B` 中的項目會加上標籤，`{host=A}`他們會加入。
+ 如果在變數中，例如每個項目`$A`有不同的標籤索引鍵，則聯結行為是未定義的。

關聯式和邏輯運算子傳回 0 表示 false 1 表示 true。

**數學函數**

雖然大多數函數存在於自己的表達式操作中，但數學操作確實有一些類似於數學運算子或符號的函數。當函數可以採用數字或序列時，將會傳回與引數相同的類型。當它是序列時，針對序列中每個點的值執行的 操作。

*abs*

abs 會傳回其引數的絕對值，可以是數字或序列。例如 `abs(-1)` 或 `abs($A)`。

*is\$1inf*

is\$1inf 採用數字或序列，並傳回`Inf`值 `1` （負值或正值） `0` 和其他值。例如 `is_inf($A)`。

**注意**  
如果您需要特別檢查負無限，例如，您可以執行 等比較`$A == infn()`。

*is\$1nan*

is\$1nan 採用數字或序列，並傳回`1``NaN`值 `0` 和其他值 。例如 `is_nan($A)`。此函數存在，因為 `NaN` 不等於 `NaN`。

*is\$1null*

is\$1null 採用數字或序列，並傳回`1``null`值 和其他`0`值 。例如 `is_null($A)`。

*is\$1number*

is\$1number 採用數字或序列，並`1`傳回所有實數值`0`和其他值 （分別為 `null`、`Inf-`、 `Inf+`和 `NaN`)。例如 `is_number($A)`。

*日誌*

Log 會傳回其引數的自然對數，可以是數字或序列。如果值小於 0，`NaN`則會傳回 。例如 `log(-1)` 或 `log($A)`。

*inf、infn、nan 和 null*

inf、infn、nan 和 null 函數都會傳回名稱的單一值。它們主要用於測試。範例：`null()`。

*四捨五入*

Round 傳回四捨五入整數值。例如 `round(3.123)` 或 `round($A)`。

*頭腦*

Ceil 會將數字四捨五入到最接近的整數值。例如，`ceil(3.123)` 傳回 `4`。

*樓層*

下限會將數字四捨五入到最接近的整數值。例如，`floor(3.123`) 會傳回 `3`。

**減少**

減少 需要一個或多個從查詢或表達式傳回的時間序列，並將每個序列轉換為單一數字。時間序列的標籤會保留為每個輸出的減少數字上的標籤。

*欄位：*
+ **函數** – 要使用的縮減函數
+ **輸入** – 要重新取樣的變數 (refID （例如 `A`))
+ **模式** – 當序列包含非數值 (null、NaN、\$1-Inf) 時，允許降低函數的控制行為

**減少函數**

*Count (計數)*

Count 會傳回每個系列中的點數。

*平均值*

平均值會傳回每個序列中所有值的總計，除以該序列中的點數。在 `strict`模式中，如果序列中的任何值為 null 或 nan，或者如果序列為空，則會傳回 NaN。

*最小值和最大值*

最小值和最大值分別傳回序列中的最小或最大值。在 `strict`模式中，如果序列中的任何值為 null 或 nan，或者如果序列為空，則會傳回 NaN。

*Sum (總和)*

總和會傳回序列中所有值的總計。如果序列長度為零，總和將為 0。在 `strict`模式中，如果系列中有任何 NaN 或 Null 值，則會傳回 NaN。

*最後一個*

上次傳回序列中的最後一個數字。如果序列沒有值，則傳回 NaN。

**減少模式**

*嚴格*

在嚴格模式下，輸入序列會照原樣處理。如果序列中的任何值是非數字 (null、NaN 或 \$1-Inf)，則會傳回 NaN。

*捨棄非數值*

在此模式中，輸入序列中的所有非數值 (null、NaN 或 \$1-Inf) 都會在執行縮減函數之前篩選掉。

*取代非數值*

在此模式中，所有非數值都會以預先定義的值取代。

**重新取樣**

重新取樣會將每個時間序列中的時間戳記變更為具有一致的時間間隔。主要使用案例是 ，因此您可以重新取樣不共用相同時間戳記的時間序列，以便在它們之間執行數學。這可以透過重新取樣兩個序列中的每個序列，然後在參考重新取樣變數的數學操作中完成。

*欄位：*
+ **輸入** – 要重新取樣的時間序列資料變數 (refID （例如 `A`))
+ **重新取樣**至 – 重新取樣的持續時間，例如`10s.`，單位可以是`s`秒、`m`分鐘、`h`小時、`d`天、`w`週和`y`年。
+ **Downsample** – 當每個視窗範例有多個資料點時要使用的減少函數。如需行為詳細資訊，請參閱減少操作。
+ **Upsample** – 用來填充沒有資料點之視窗範例的方法。
  + **鍵盤**會填入最後一個已知值
  + 回**填**下一個已知值
  + **fillna** 以 NaNs填滿空的範例時段

## 撰寫表達式
<a name="v9-panels-query-write"></a>

如果您的資料來源支援，則 Grafana 會顯示**表達式**按鈕，並在查詢編輯器清單中顯示任何現有的表達式。

**撰寫表達式**

1. 開啟面板。

1. 在查詢下方，選擇**表達式**。

1. 在**操作**欄位中，選取您要寫入的表達式類型。

1. 撰寫表達式。

1. 選擇**套用**。

## 特殊案例
<a name="v9-panels-query-special"></a>

當任何查詢的資料來源未傳回任何序列或數字時，表達式引擎會傳回 `NoData`。例如，如果請求包含兩個由 表達式合併的資料來源查詢，如果由至少一個資料來源查詢`NoData`傳回，則整個查詢傳回的結果為 `NoData`。如需 Grafana 警示如何處理`NoData`結果的詳細資訊，請參閱 [不處理任何資料或錯誤案例](v9-alerting-managerules-grafana.md#v9-alerting-rule-no-data-error)。