1. 程式人生 > 其它 >10分鐘簡單學習net core整合jwt許可權認證,快速接入專案落地使用

10分鐘簡單學習net core整合jwt許可權認證,快速接入專案落地使用

為什麼需要聚合

一般查詢可以通過 find() 方法,但如果是比較複雜的查詢或者資料統計的話,find() 方法可能就無能為力,這時需要聚合(aggregate)。

聚合操作處理資料文件並返回計算結果。聚合操作將來自多個文件的值分組在一起,可以對分組的資料執行各種操作以返回單個結果。

MongoDB 提供了三種執行聚合的方法:

  • 聚合管道
  • map- reduce 函式
  • 單一目的聚合方法
什麼是聚合管道(aggregation pipeline)

聚合管道可以對資料文件進行變換和組合。聚合管道是基於資料流概念,資料進入管道經過一個或多個 stage,每個 stage 對資料進行操作(篩選,投射,分組,排序,限制或跳過)後輸出最終結果。

聚合管道語法

db.collection.aggregate(pipeline, options)
  • pipeline:陣列型別

注:聚合管道可以對分片集合進行操作

Pipeline 管道
db.collection.aggregate( [ { <stage> },... ] )

MongoDB 聚合管道由多個 stage 階段組成。每個 stage 階段在文件通過管道時轉換文件。管道階段可以在管道中出現多次。

聚合管道原理

db.collection.aggregate([]) 是聚合管道查詢使用的方法,引數是陣列,每個陣列元素就是一個stage,stage 中運用操作符對資料進行處理後再交由下一個stage,直到沒有下個stage,就輸出最終的結果,而資料的處理則是通過使用管道操作符。

什麼是管道操作符

mongoDB 有 4 類操作符用於文件的操作(操作符以 $ 開頭)

  • 查詢操作符
  • 更新操作符
  • 管道操作符(聚合管道中的操作符)
  • 查詢修飾符

在 aggregate 中每個 stage 可以使用的操作符叫做管道操作符

管道操作符分類
  • 階段操作符(Stage Operators)
  • 表示式操作符(Expression Operators)
  • 累加器(Accumulators)
階段操作符
db.collection.aggregate( [ { 階段操作符:表述 }, { 階段操作符:表述 }, ... ] )
階段操作符 操作符名稱 說明
$count 統計操作符 用於統計文件的數量
$group 分組操作符 用於對文件集合進行分組
$limit 限制操作符 用於限制返回文件的數量
$match 匹配操作符 用於對文件集合進行篩選
$out 輸出操作符 將聚合管道的結果文件寫入集合。要使用 $out階段,它必須是管道中的最後一個階段。
$project 投射操作符 用於重構每一個文件的欄位,可以提取欄位,重新命名欄位,甚至可以對原有欄位進行操作後新增欄位
$skip 跳過操作符 用於跳過指定數量的文件
$sort 排序操作符 用於根據一個或多個欄位對文件進行排序
$unwind 拆分操作符 用於將陣列中的每一個值拆分為單獨的文件
$lookup 連線操作符 用於連線同一個資料庫中另一個集合,並獲取指定的文件,類似於populate
$addFields 欄位操作符 用於給聚合管道的結果文件新增欄位

$match 語法

匹配操作符,用於對文件集合進行篩選

{ $match: { <query> } }

$project 語法

用於重構每一個文件的欄位,可以提取欄位,重新命名欄位,甚至可以對原有欄位進行操作後新增欄位

{ $project: { <specification(s)> } } 

specification 的規則如下:

規則 描述
<欄位名>: 1 or true 選擇需要顯示什麼欄位
_id: 0 or false 不顯示 _id (預設顯示)
<欄位名>: 表示式 使用表示式,可以用於重新命名欄位,或對其值進行操作,或新增欄位
<欄位名>: 0 or false 選擇需要不返回什麼欄位,注意:當使用這種用法時,就不要用上面的方法

$addFields 語法

在聚合管道結果新增一些欄位資訊或者修改欄位資訊

{ $addField: <document> }

$skip 語法

用於跳過指定數量的文件

{ $skip: <positive integer> }

$limit 語法

用於限制返回文件的數量

{ $limit: <positive integer> }

$count 語法

{ $count: <string> } 
  • string:是輸出欄位的名稱,該欄位的值為 count。string 必須是非空字串,不能以 $ 開頭,也不能包含 .點字元

$sort 語法

用於根據一個或多個欄位對文件進行排序

{ $sort: { <field1>: <sort order>,<field2>: <sort order> ... } }
  • 1:升序
  • -1:降序

$out 語法

{ $out: "<output-collection>" }

$unwind 語法

用於將陣列中的每一個值拆分為單獨的文件

{	$unwind:	{		path: <field path>, includeArrayIndex: <string>, 		preserveNullAndEmptyArrays:<boolean>	} }
  • path:字串型別,陣列欄位的欄位路徑,若要指定欄位路徑,需要在欄位名稱前加上 $ 符號並將其括在引號內
  • includeArrayIndex:可選項,用於儲存元素的陣列索引的新欄位的名稱。名稱不能以 $ 符號開頭
  • preserveNullAndEmptyArrays:
    • 如果為 true,如果路徑為空、沒有陣列欄位或陣列為空,則 $unwind 輸出文件
    • 如果為 false,如果路徑為空、沒有陣列欄位或陣列為空,則 $unwind 不輸出文件(預設)

$lookup 語法

用於連線同一個資料庫中另一個集合,並獲取指定的文件

{   $lookup:     {       from: <collection to join>,       localField: <field from the input documents>,       foreignField: <field from the documents of the "from" collection>,       as: <output array field>     }}
欄位 描述
from 需要關聯的集合名
localField 本集合中需要查詢的欄位
foreignField 另外一個集合中需要關聯的欄位
as 輸出的欄位名

$group 語法

用於對文件集合進行分組

{ $group: { _id: <expression>, <field1>: { <accumulator1> : <expression1> }, ... } }
  • _id:是必須的,用作分組的依據條件

表示式(Expression)

表示式可以包括欄位路徑和系統變數、文字、表示式物件和表示式操作符。表示式可以巢狀。

{ <field1>: <expression1>, ... }
  • 欄位路徑表示式:$

  • "$<field>” 等價於 “$$CURRENT.<field>”,其中 CURRENT 是一個系統變數,在大多數階段預設為當前物件的根.

  • 聚合表示式使用欄位路徑訪問輸入文件中的欄位。若要指定欄位路徑,請使用字首為$符號欄位名的字串,如果欄位在嵌入的文件中,則使用點語法。

  • 系統變量表達式:$$系統變數

    • $$CURRENT 表示當前文件

    • $$ROOT 整個文件

  • 字面量表達式:返回不需要解析的值。用於聚合管道可解釋為表示式的值

  • 表示式物件

  • 表示式操作符

表示式操作符

表示式操作符主要用於在管道中構建表示式時使用,使用類似於函式那樣需要引數,主要用於 $project 操作符中,用於構建表示式,使用方法一般如下:

{ <operator>: [ <argument1>, <argument2> ... ] }# 或{ <operator>: <argument> }
表示式操作符分類
  • 布林值操作符(Boolean Operators)
  • 集合操作符(Set Operators)
  • 比較操作符(Comparison Operators)
  • 數學操作符(Arithmetic Operators)
  • 字串操作符(String Operators)
  • 文字搜尋操作符(Text Search Operators)
  • 陣列操作符(Array Operators)
  • 變數操作符(Variable Operators)
  • 字面量操作符(Literal Operators)
  • 日期操作符(Date Operators)
  • 條件操作符(Conditional Operators)
  • 資料型別操作符(Data Type Operators)
累加器(Accumulators)
累加器操作符 說明
$avg 返回數值的平均值(忽略非數字值)
$max 返回每個組的最高表示式值
$min 返回每個組的最低表示式值
$push 返回每個組的表示式值組成的陣列
$sum 返回數值的和(忽略了非數字值)

$avg 語法

{ $avg: [ <expression1>, <expression2>... ] }

$max 語法

{ $max: <expression> }{ $max: [ <expression1>, <expression2>... ] }

$push 語法

{ $push: <expression> }

$sum 語法

{ $sum: <expression> }

聚合管道優化

聚合管道操作有一個優化階段,該階段試圖重塑管道以提高效能

管道序列優化
  • $project or $addFields) 和 $match 順序優化

  • $sort 和 $match 順序優化

  • $skip 和 $limit 順序優化

  • $project 和 ($skip or $limit) 順序優化

管道聯合優化
  • $sort 和 $limit 聯合優化

當 $sort 緊鄰 $limit 時,優化器可以將 $limit 合併到 $sort 中。這允許 $sort 操作在進行過程中只維護頂部的 n 個結果,其中 n 是指定的限制,MongoDB 只需要在記憶體中儲存 n 個條目。

  • $limit 和 $limit 聯合優化

當一個 $limit 緊接另一個 $limit 之後,這兩個階段可以合併為一個 $limit,其中 $limit 值是兩個初始 $limit 值中較小的一個。

  • $skip 和 $skip 聯合優化

當一個 $skip 緊接著另一個 $skip 時,這兩個階段可以合併為單個 $skip,其中 $skip 量是兩個初始 $skip 量的總和。

  • $match 和 $match 聯合優化

當一個 $match 緊跟在另一個 $match 之後時,這兩個階段可以合併為一個結合了條件和 $and 的單個 $match

  • $sort 和 $skip 和 $limit 聯合優化

  • $limit 和 $skip 和 $limit 和 $skip 聯合優化