es筆記七之聚合操作之桶聚合和矩陣聚合

来源:https://www.cnblogs.com/hunterxiong/archive/2023/05/25/17433331.html
-Advertisement-
Play Games

> 本文首發於公眾號:Hunter後端 > 原文鏈接:[es筆記七之聚合操作之桶聚合和矩陣聚合](https://mp.weixin.qq.com/s/SFiLEtnUqxncL-ZQj1zqgg) 桶(bucket)聚合併不像指標(metric)聚合一樣在欄位上計算,而是會創建數據的桶,我們可以理 ...


本文首發於公眾號:Hunter後端
原文鏈接:es筆記七之聚合操作之桶聚合和矩陣聚合

桶(bucket)聚合併不像指標(metric)聚合一樣在欄位上計算,而是會創建數據的桶,我們可以理解為分組,根據某個欄位進行分組,將符合條件的數據分到同一個組裡。

桶聚合可以有子聚合,意思就是在分組之後,可以在每個組裡再次進行聚合操作,聚合的數據就是每個組的數據。

以下是本篇筆記目錄:

  1. 基本桶聚合操作
  2. 過濾聚合
  3. 多桶過濾聚合
  4. 全局聚合
  5. 直方圖聚合
  6. 嵌套聚合
  7. 範圍聚合
  8. 稀有詞聚合
  9. 矩陣聚合

1、基本桶聚合操作

我們可以簡單的先來進行一下桶聚合的操作,比如我們根據 age 欄位對數據進行分組操作:

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "bucket_age": {
      "terms": {
        "field": "age",
        "size": 20
      }
    }
  }
}

返回的數據如下:

{
  ...
  "aggregations" : {
    "bucket_age" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 35,
      "buckets" : [
        {
          "key" : 31,
          "doc_count" : 61
        },
        {
          "key" : 39,
          "doc_count" : 60
        },
        {
          "key" : 26,
          "doc_count" : 59
        },
        ...
      ]
    }
  }
}     

所有的數據在 aggregations.bucket_age.buckets 下,這是一個數組,key 的內容為 age 的值,doc_count 為該 age 值的數據條數。

其中,bucket_age 為我們定義的桶聚合的名稱。

接下來我們介紹桶聚合和指標聚合的其他操作。

2、過濾聚合

如果我們想針對某特定的數據進行聚合,那麼就涉及數據的過濾,篩選出特定的數據進行聚合。

比如我們想篩選出 gender 的值為 "F" 的數據,然後對其進行取平均數的操作,我們可以使用 filter 來如下操作:

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "bucket_gender": {
      "filter": {"term": {"gender.keyword": "F"}},
      "aggs": {
        "avg_balance": {"avg": {"field": "balance"}}
      }
    }
  }
}

aggs.bucket_gender 我們使用 filter 對數據進行了一個過濾,篩選出 gender 的值為 "F" 的數據。

註意,在這裡,因為我們寫入數據前,沒有預先定義欄位的類型,所以 es 中將其自動轉化成 text 屬性的欄位,所以在查詢的時候用到的是 gender.keyword,意思是對 gender 欄位的內容作為整體進行篩選。

如果本身是 keyword 屬性,就不用加 .keyword 來操作。

與 filter 同級的 aggs,進行針對篩選出的數據進行聚合的操作,這裡我們用到的是平均值。

返回的數據如下:

  ...
  "aggregations" : {
    "bucket_gender" : {
      "doc_count" : 493,
      "avg_balance" : {
        "value" : 25623.34685598377
      }
    }
  }
}

3、多桶過濾聚合

在上一點我們過濾的是單個條件,gender='F' 的情況,如果我們想要實現多個過濾來操作,可以使用 filters,使用方法也不一樣。

比如我們想分別對 gender 的值為 F 和 M 的數據進行均值操作,我們可以一步步來操作,我們先來通過 filters 實現兩個桶的聚合:

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "bucket_gender": {
      "filters": {
        "filters": {
          "female": {"term": {"gender.keyword": "F"}},
          "male": {"term": {"gender.keyword": "M"}}
        }
      }
    }
  }
}

返回的數據就是兩個桶,包含了兩類數據的總數:

  ...
  "aggregations" : {
    "bucket_gender" : {
      "buckets" : {
        "female" : {
          "doc_count" : 493
        },
        "male" : {
          "doc_count" : 507
        }
      }
    }
  }
}

如果想在此基礎上接著對其進行均值計算,和前面的 filter 操作一樣,在第一個 filters 同級的地方,加上我們的指標聚合操作:

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "bucket_gender": {
      "filters": {
        "filters": {
          "female": {"term": {"gender.keyword": "F"}},
          "male": {"term": {"gender.keyword": "M"}}
        }
      },
      "aggs": {
        "avg_balance": {"avg": {"field": "balance"}}
      }
    }
  }
}

這樣,在返回的桶的數據之內,還包含了一個均值的結果:

  ...
  "aggregations" : {
    "bucket_gender" : {
      "buckets" : {
        "female" : {
          "doc_count" : 493,
          "avg_balance" : {
            "value" : 25623.34685598377
          }
        },
        "male" : {
          "doc_count" : 507,
          "avg_balance" : {
            "value" : 25803.800788954635
          }
        }
      }
    }
  }
}

這裡我們因為 gender 只有 F 和 M 兩個值,所以沒有第三類數據,對於其他數據,比如 age,有很多值,除了某幾種特定的值外,我們還想獲取剩下的值的信息,如何操作呢?

這裡使用到 other_bucket_key 這個參數,比如我們除了定義的 female 和 male,我們還定義一個 non_gender 欄位來統計非 M 和 F 的值,我們可以這樣操作:

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "bucket_gender": {
      "filters": {
        "other_bucket_key": "non_gender", 
        "filters": {
          "female": {"term": {"gender.keyword": "F"}},
          "male": {"term": {"gender.keyword": "M"}}
        }
      }
    }
  }
}

返回的值如下:

  ...
  "aggregations" : {
    "bucket_gender" : {
      "buckets" : {
        "female" : {
          "doc_count" : 493,
          "avg_balance" : {
            "value" : 25623.34685598377
          }
        },
        "male" : {
          "doc_count" : 507,
          "avg_balance" : {
            "value" : 25803.800788954635
          }
        },
        "non_gender" : {
          "doc_count" : 0,
          "avg_balance" : {
            "value" : null
          }
        }
      }
    }
  }
}

4、全局聚合

如果我們要在限定的範圍內進行聚合,但是又想在全局範圍內獲取聚合數據進行比對。

比如說,我們在 gender='F' 的範圍進行聚合操作:

GET /bank/_search
{
  "size": 0, 
  "query": {"match": {"gender.keyword": "F"}},
  "aggs": {
    "female_balance_avg": {
      "avg": {
        "field": "balance"
      }
    }
  }
}

這裡通過 query 操作篩選 gender='F' 的數據,然後對 balance 欄位進行聚合,如果同時我們想要獲取所有數據的 balance 的平均值,我們可以使用 global 來操作,如下:

GET /bank/_search
{
  "size": 0, 
  "query": {"match": {"gender.keyword": "F"}},
  "aggs": {
    "total_balance_avg": {
      "global": {},
      "aggs": {
        "avg_balance": {
          "avg": {"field": "balance"}
        }
      }
    },
    "female_balance_avg": {
      "avg": {
        "field": "balance"
      }
    }
  }
}

這樣就有兩個數據來比對,結果如下:

  ...
  "aggregations" : {
    "female_balance_avg" : {
      "value" : 25623.34685598377
    },
    "total_balance_avg" : {
      "doc_count" : 1000,
      "avg_balance" : {
        "value" : 25714.837
      }
    }
  }
}

5、直方圖聚合

這是個類似於直方圖的區間桶的聚合操作。

比如對於 age 欄位,我們想以 5 為步長進行聚合,如果 age 欄位在 20-50 之間,那麼返回的數據就會類似於 20-24,25-29,30-34... 以及落在這些區間的數據的數量。

而返回的每條數據並不會是一個區間,而是一個開始的數據,也就是說上面的例子會返回的 key 是 20,25,30 等。

比如我們想對 age 欄位進行直方圖聚合,步長為 5,用到的聚合的欄位為 histogram,示例如下:

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "age_histogram": {
      "histogram": {
        "field": "age",
        "interval": 5
      }
    }
  }
}

在 histogram 聚合欄位下,field 欄位為我們要進行直方圖聚合的欄位,這裡是 age 欄位,interval 欄位為進行劃分的區間,我們定義為 5。

返回的數據如下:

  ...
  "aggregations" : {
    "age_histogram" : {
      "buckets" : [
        {
          "key" : 20.0,
          "doc_count" : 225
        },
        {
          "key" : 25.0,
          "doc_count" : 226
        }
        ...
    ]
  }
}    

註意: 如果我們進行聚合的區間,比如說 25-29 之間聚合的數據是 0,那麼 es 還是會返回這個區間,不過 doc_count 是 0,不會存在不返回這個區間 key 的情況。

最小 count 返回數據

前面我們說了就算區間 count 數是0,這個區間也會返回,但同時我們也可以規定 min_doc_count 這個參數來返回只有當區間 count 數大於等於這個值的時候才返回數據。

假設 age 的區間數據如下:

20-24:5

25-29:0

30-34:2
...

如果我們設置 min_doc_count=2,那麼返回的區間 25-29則不會被返回,使用示例如下:

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "age_histogram": {
      "histogram": {
        "field": "age",
        "interval": 5,
        "min_doc_count": 2
      }
    }
  }
}

返回數據:

  ...
  "aggregations" : {
    "age_histogram" : {
      "buckets" : [
        {
          "key" : 20.0,
          "doc_count" : 5
        },
        {
          "key" : 30.0,
          "doc_count" : 2
        },
        ...
     ]
   }
 }

指定返回區間

前面介紹的示例中,如果數據在 20-50 之間,那麼返回的區間數據就從 20 開始計數(具體的 key 會根據 interval 的設置不一樣,比如設置 Interval=5,key 就會是 20, 25, 30...,如果是設置 Interval=3,那麼 key 就會是 18, 21, 24...)。

如果我們想從 0 開始計數,即便是 0-20 之間的計數為 0,也想要返回20之前 0-4,5-9 的數,或者想要返回 50 之後的數據,包括 50-54,55-59 這種,我們可以使用extended_bounds.minextended_bounds.max 來限定返回數據的最大最小值,示例如下:

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "age_histogram": {
      "histogram": {
        "field": "age",
        "interval": 5,
        "extended_bounds": {
          "min": 0,
          "max": 90
        }
      }
    }
  }
}

這樣返回的數據的區間就會在 0-90 之間,即便在全量數據的範圍之外。

註意: 因為在數據區間之外的數據為 0,想要擴展的區間返回顯示,記得要將最小返回計數值 min_doc_count 置為 0。

6、嵌套聚合

嵌套聚合,這裡針對的是 es 中數據欄位為數組,數組元素里又嵌套為對象的情況,官方文檔舉了個例子,新建一個 products 的 index,數據結構如下:

PUT /products
{
    "mappings": {
        "properties" : {
            "resellers" : { 
                "type" : "nested",
                "properties" : {
                    "reseller" : { "type" : "text" },
                    "price" : { "type" : "double" }
                }
            }
        }
    }
}

接下來我們往裡添加兩條條數據:

PUT /products/_doc/0
{
  "name": "LED TV", 
  "resellers": [
    {
      "reseller": "companyA",
      "price": 350
    },
    {
      "reseller": "companyB",
      "price": 500
    }
  ]
}

PUT /products/_doc/1
{
  "name": "LED TV", 
  "resellers": [
    {
      "reseller": "companyA",
      "price": 400
    },
    {
      "reseller": "companyB",
      "price": 250
    }
  ]
}

然後我們想要在這兩條數據里的 resellers 數組欄位里的四個元素里獲取 price 欄位最小值,可以通過 nested.path 來指定 resellers 欄位,然後進行聚合,使用示例如下:

GET /products/_search
{
    "size": 0, 
    "query" : {
        "match" : { "name" : "led tv" }
    },
    "aggs" : {
        "resellers" : {
            "nested" : {
                "path" : "resellers"
            },
            "aggs" : {
                "min_price" : { "min" : { "field" : "resellers.price" } }
            }
        }
    }
}

7、範圍聚合

範圍聚合,即 range 聚合。我們可以通過指定範圍來返回各個桶的數據,這個操作和直方圖聚合是類似的,不過這個操作更靈活,聚合的範圍不會寫死。

如果是希望步長固定,我們可以使用直方圖聚合,比如0-4,5-9 這種,如果我們直接想要自定義的 0-7,8-19 這種我們想要定義的可以使用範圍聚合。

還是使用 age 欄位來操作,比如我們想要獲取 小於27,28-35,大於36 這個範圍,我們可以如下操作:

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "age_range": {
      "range": {
        "field": "age",
        "ranges": [
          {"to": 27},
          {"from": 27, "to": 35},
          {"from": 35}
        ]
      }
    }
  }
}

需要註意的是,from 的參數是開區間的,比如我們這裡 from=27,那麼邏輯就是 >27,如果區間兩邊沒有限制,不填寫相應的 from 和 to 參數即可,返回的 key 也會是 *-27 這種形式。

上面的命令返回的數據如下:r

  ...
  "aggregations" : {
    "age_range" : {
      "buckets" : [
        {
          "key" : "*-27.0",
          "to" : 27.0,
          "doc_count" : 326
        },
        {
          "key" : "27.0-35.0",
          "from" : 27.0,
          "to" : 35.0,
          "doc_count" : 384
        },
        {
          "key" : "35.0-*",
          "from" : 35.0,
          "doc_count" : 290
        }
      ]
    }
  }
}

如果想要返回的數據以 key:{} 的形式返回,可以加上 keyed=true 參數:

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "age_range": {
      "range": {
        "field": "age",
        "keyed": true,
        "ranges": [
          {"to": 27},
          {"from": 27, "to": 35},
          {"from": 35}
        ]
      }
    }
  }
}

桶的子指標聚合

在上面的桶聚合操作之後,我們還可以對每個桶進行子指標聚合,比如說最大最小值,平均值,或者統計值等,以下是個操作示例:

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "age_range": {
      "range": {
        "field": "age",
        "ranges": [
          {"to": 27},
          {"from": 27, "to": 35},
          {"from": 35}
        ]
      },
      "aggs": {
        "age_stats": {
          "stats": {
            "field": "age"
          }
        }
      }
    }
  }
}

進行指標聚合的範圍是分到每個桶的數據。

8、稀有詞聚合

rare terms aggregation,這個的概念大概是這樣的,比如我們根據 age 欄位進行聚合,統計他們在文檔中出現的次數,我們想要獲取出現次數最少的幾個,或者指定出現次數少於 50 的 age 值,就可以用到這個操作。

接下來我們對 age 欄位進行這樣的操作,只獲取出現次數少於 50 的數據,示例如下:

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "rare_age": {
      "rare_terms": {
        "field": "age",
        "max_doc_count": 50
      }
    }
  }
}

這個的關鍵字是 rare_terms,rare_age 是我們指定的聚合名稱,其下 field 是我們進行聚合欄位,在這裡是 age 欄位,max_doc_count 則是我們指定的出現次數最大的值。

返回的數據會按照 doc_count 正序排列返回,大致如下:

  ...
  "aggregations" : {
    "rare_age" : {
      "buckets" : [
        {
          "key" : 29,
          "doc_count" : 35
        },
        {
          "key" : 27,
          "doc_count" : 39
        },
        {
          "key" : 38,
          "doc_count" : 39
        },
        ...

範圍過濾

我們還可以使用過濾的方式來指定或者排除某些值,這個操作是支持正則的,但經過測試,發現按照官方文檔使用正則的 * 來篩選數據並不能真正起作用,所以這裡我們介紹使用列表來實現過濾。

比如我們指定的 age 範圍是 [29, 27, 24],使用 include:

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "rare_age": {
      "rare_terms": {
        "field": "age",
        "max_doc_count": 51,
        "include": [29, 27, 24]
      }
    }
  }
}

如果我們要排除的 age 範圍是 [29, 27, 24],使用 exclude:

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "rare_age": {
      "rare_terms": {
        "field": "age",
        "max_doc_count": 51,
        "exclude": [29, 27, 24]
      }
    }
  }
}

9、矩陣聚合

矩陣聚合是很小的一部分,這裡直接介紹一下。

前面在指標聚合的介紹中,有一個聚合統計彙總,其中介紹了一個參數是 stats,會返回對應欄位的最大值、最小值、總數等數據,矩陣聚合 matrix 可以理解成是多個欄位的 stats 的集合,會缺少一些統計值,但是返回的值更偏統計學方面的用途。

使用示例如下:

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "field_statis": {
      "matrix_stats": {
        "fields": ["age", "balance"]
      }
    }
  }
}

返回的數據如下:

  ...
  "aggregations" : {
    "field_statis" : {
      "doc_count" : 1000,
      "fields" : [
        {
          "name" : "balance",
          "count" : 1000,
          "mean" : 25714.837000000014,
          "variance" : 1.9757153733576667E8,
          "skewness" : -0.009992486755643138,
          "kurtosis" : 1.8088323899074914,
          "covariance" : {
            "balance" : 1.9757153733576667E8,
            "age" : -2845.650777777781
          },
          "correlation" : {
            "balance" : 1.0,
            "age" : -0.033676422195874786
          }
        },
        {
          "name" : "age",
          "count" : 1000,
          ...
        }
    ...

其中,各參數的釋義如下:

count: 總數

mean: 平均值

variance: 方差

skewness: 偏度

kurtosis: 峰度

covariance: 協方差

correlation: 與其他欄位的相關性,比如 age 到 age 欄位的相關性就是 1.0

如果想獲取更多後端相關文章,可掃碼關註閱讀:
image


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Centos7安裝配置 # 一 、 安裝 安裝就不多做詳述,選擇好自己的鏡像設置好路徑即可 # 二 、配置 #### 2.1 網路配置 桌面右鍵進入 `cmd` 命令編輯視窗,在 Linux 中設置網路的相關配置都需要管理員許可權,需要先切換到 root 用戶。 ```markdown vim /et ...
  • # 伺服器磁碟滿了!!! 事發突然,我在給博客的圖片新增的時候,發現上傳文件和下載文件一直報錯。因為我用的是`1Panel`面板去管理伺服器,話不多說看圖: ![image](https://img2023.cnblogs.com/blog/3091176/202305/3091176-202305 ...
  • 目錄 一、shell簡述 二、shell腳本 三、重定向 四、管道符 五、變數 六、shell腳本基本知識 七、預定義變數小實驗 一、shell簡述 概念:shell解釋器,翻譯官功能,與內核進行溝通的應用程式。 把代碼翻譯為二進位,讓內核處理,負責接收用戶輸入的操作指令(命令)併進行解釋,將需要執 ...
  • 需要先安裝svn linux版打開終端執行 sudo pacman -S svn 安裝完成後執行一下 svn --version 出現這個就說明svn已經安裝完成了,這個時候我們可以執行 svn checkout [路徑] 就可以檢出svn伺服器上相關內容了 但是這個有的時候我們打開文件管理器想要看 ...
  • ZBar是一種流行的二維碼掃描和解碼工具,它在嵌入式系統中擁有廣泛的應用。在嵌入式系統中,我們面臨著有限的資源和更嚴格的性能要求,因此,選擇適當的庫來完成特定的任務非常重要。 ZBar適用於各種嵌入式平臺,包括ARM、x86和MIPS等處理器架構。它可以輕鬆地整合到各種嵌入式系統中,如智能家居設備、 ...
  • 大家新年好,我是呼嚕嚕,在上一篇[簡易加法器](https://mp.weixin.qq.com/s/ahuk_JH8iyH8bwh3VQxpOw)里我們瞭解了半加器和全加器的設計與實現,今天我們來看下CPU中減法器是如何實現的。文章比較長,大家可以收藏反覆觀看 ## 電腦為什麼利用反碼來實現減法 ...
  • Mysql-8.0.27安裝包位置:https://pan.baidu.com/s/1DFfDlnmCh3qVaj091qcpNA 提取碼:vmny 1.首先我們需要準備一個Linux環境,和一個MySql的安裝包(本次採用的mysql安裝包版本為:8.0.27) 2.把文件放在linux下的/us ...
  • 哈嘍大家好,我是鹹魚 鹹魚在《[一文帶你瞭解容器技術的前世今生](https://mp.weixin.qq.com/s?__biz=MzkzNzI1MzE2Mw==&mid=2247484578&idx=1&sn=a8ae0d1c470351a8bbcb6891bae0ca23&chksm=c293 ...
一周排行
    -Advertisement-
    Play Games
  • Timer是什麼 Timer 是一種用於創建定期粒度行為的機制。 與標準的 .NET System.Threading.Timer 類相似,Orleans 的 Timer 允許在一段時間後執行特定的操作,或者在特定的時間間隔內重覆執行操作。 它在分散式系統中具有重要作用,特別是在處理需要周期性執行的 ...
  • 前言 相信很多做WPF開發的小伙伴都遇到過表格類的需求,雖然現有的Grid控制項也能實現,但是使用起來的體驗感並不好,比如要實現一個Excel中的表格效果,估計你能想到的第一個方法就是套Border控制項,用這種方法你需要控制每個Border的邊框,並且在一堆Bordr中找到Grid.Row,Grid. ...
  • .NET C#程式啟動閃退,目錄導致的問題 這是第2次踩這個坑了,很小的編程細節,容易忽略,所以寫個博客,分享給大家。 1.第一次坑:是windows 系統把程式運行成服務,找不到配置文件,原因是以服務運行它的工作目錄是在C:\Windows\System32 2.本次坑:WPF桌面程式通過註冊表設 ...
  • 在分散式系統中,數據的持久化是至關重要的一環。 Orleans 7 引入了強大的持久化功能,使得在分散式環境下管理數據變得更加輕鬆和可靠。 本文將介紹什麼是 Orleans 7 的持久化,如何設置它以及相應的代碼示例。 什麼是 Orleans 7 的持久化? Orleans 7 的持久化是指將 Or ...
  • 前言 .NET Feature Management 是一個用於管理應用程式功能的庫,它可以幫助開發人員在應用程式中輕鬆地添加、移除和管理功能。使用 Feature Management,開發人員可以根據不同用戶、環境或其他條件來動態地控制應用程式中的功能。這使得開發人員可以更靈活地管理應用程式的功 ...
  • 在 WPF 應用程式中,拖放操作是實現用戶交互的重要組成部分。通過拖放操作,用戶可以輕鬆地將數據從一個位置移動到另一個位置,或者將控制項從一個容器移動到另一個容器。然而,WPF 中預設的拖放操作可能並不是那麼好用。為瞭解決這個問題,我們可以自定義一個 Panel 來實現更簡單的拖拽操作。 自定義 Pa ...
  • 在實際使用中,由於涉及到不同編程語言之間互相調用,導致C++ 中的OpenCV與C#中的OpenCvSharp 圖像數據在不同編程語言之間難以有效傳遞。在本文中我們將結合OpenCvSharp源碼實現原理,探究兩種數據之間的通信方式。 ...
  • 一、前言 這是一篇搭建許可權管理系統的系列文章。 隨著網路的發展,信息安全對應任何企業來說都越發的重要,而本系列文章將和大家一起一步一步搭建一個全新的許可權管理系統。 說明:由於搭建一個全新的項目過於繁瑣,所有作者將挑選核心代碼和核心思路進行分享。 二、技術選擇 三、開始設計 1、自主搭建vue前端和. ...
  • Csharper中的表達式樹 這節課來瞭解一下表示式樹是什麼? 在C#中,表達式樹是一種數據結構,它可以表示一些代碼塊,如Lambda表達式或查詢表達式。表達式樹使你能夠查看和操作數據,就像你可以查看和操作代碼一樣。它們通常用於創建動態查詢和解析表達式。 一、認識表達式樹 為什麼要這樣說?它和委托有 ...
  • 在使用Django等框架來操作MySQL時,實際上底層還是通過Python來操作的,首先需要安裝一個驅動程式,在Python3中,驅動程式有多種選擇,比如有pymysql以及mysqlclient等。使用pip命令安裝mysqlclient失敗應如何解決? 安裝的python版本說明 機器同時安裝了 ...