https://segmentfault.com/a/1190000010910985
管道操作符的分類
管道操作符可以分為三類:
- 階段操作符(Stage Operators)
- 表達式操作符(Expression Operators)--主要用于$project
- 累加器(Accumulators)--主要用于$group分組
表達式操作符(Expression Operators)
表達式操作符主要用于在管道中建構表達式時使用,使用類似于函數那樣需要參數,主要用于$project操作符中,用于建構表達式,使用方法一般如下:
方法1:
{ <operator>: [ <argument1>, <argument2> ... ] }
方法2:
{ <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)
常用表達式操作符
操作符 | 簡述 |
---|---|
$and | 邏輯與操作符,當他的表達式中所有值都是true的時候,才傳回true。 用法: 。 |
$or | 邏輯或操作符,當他的表達式中有值是true的時候,就會傳回true。用法: |
$not | 取反操作符,傳回表達式中取反後的布爾值。用法: |
示例
例子 | 結果 |
---|---|
| true |
| |
| |
| false |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
$cmp | 比較操作符,比較表達式中兩個值的大小,如果第一個值小于第二個值則傳回-1,相等傳回0,大于傳回1。用法 |
$eq | 比較表達式中兩個是否相等,是則傳回true,否則傳回false。用法 |
$gt | 比較表達式中第一個值是否大于第二個值,是則傳回true,否則傳回false。用法 |
$gte | 比較表達式中第一個值是否大于等于第二個值,是則傳回true,否則傳回false。用法 |
$lt | 比較表達式中第一個值是否小于第二個值,是則傳回true,否則傳回false。用法 |
$lte | 比較表達式中第一個值是否小于等于第二個值,是則傳回true,否則傳回false。用法 |
$ne | 比較表達式中兩個是否相等,不過傳回值與$eq相反,是則傳回false,否則傳回true。用法 |
假設有一個關于考試成績的集合:
{ "_id" : 1, "name" : "abc1", score: 80 }
{ "_id" : 2, "name" : "avc1", score: 82 }
{ "_id" : 3, "name" : "adc1", score: 79 }
{ "_id" : 4, "name" : "awc1", score: 60 }
{ "_id" : 5, "name" : "xyz1", score: 50 }
{ "_id" : 6, "name" : "VWZ1", score: 100 }
操作如下:
db.collection.aggregate(
[
{
$project:
{
name: 1,
score: 1,
cmp60: { $cmp: [ "$score", 60 ] },
eq100: { $eq: [ "$score", 100 ] },
gt80: { $gt: [ "$score", 80 ] },
gte80: { $gte: [ "$score", 80 ] },
lt80: { $lt: [ "$score", 80 ] },
lte80: { $lte: [ "$score", 80 ] },
ne100: { $ne: [ "$score", 100 ] },
_id: 0
}
}
]
)
傳回結果:
{ "name" : "abc1", score: 80, cmp60: 1, eq100: false, gt80: false, gte80: true, lt80: false, lte80: true, ne100: true }
{ "name" : "avc1", score: 82, cmp60: 1, eq100: false, gt80: true, gte80: true, lt80: false, lte80: false, ne100: true }
{ "name" : "adc1", score: 79, cmp60: 1, eq100: false, gt80: false, gte80: false, lt80: true, lte80: false, ne100: true }
{ "name" : "awc1", score: 60, cmp60: 0, eq100: false, gt80: false, gte80: false, lt80: true, lte80: true, ne100: true }
{ "name" : "xyz1", score: 50, cmp60: -1, eq100: false, gt80: false, gte80: false, lt80: true, lte80: true, ne100: true }
{ "name" : "VWZ1", score: 100, cmp60: 1, eq100: true, gt80: true, gte80: true, lt80: false, lte80: false, ne100: false }
$abs | 求絕對值操作符,于v3.2版新加入。用法: |
$add | 求和操作符,傳回所有表達式相加起來的結果。用法: |
$ceil | 進一法取整操作符,取 于v3.2版新加入。用法: |
$divide | 求商操作符,傳回表達式1除以表達式2的商。用法: |
$subtract | 求差操作符,傳回表達式1減去表達式2的結果。用法: |
$multiply | 求積操作符,傳回所有表達式相乘的結果。用法: |
$mod | 求餘操作符,傳回所有表達式1除以表達式2所得到的餘數。用法: |
| 1 |
| |
| null |
| 2 |
| |
| 8 |
| -2 |
| 5 |
| |
| 40 |
| 3 |
|
Tips:将一個日期類型和數字類型相加會變成日期類型。 這樣的話,當資料庫存儲的是時間戳但是需要又想對其使用日期操作符的話,就可以通過這樣的方法,先讓其變成日期類型,然後再使用日期操作符,用法參考:
$add
{ $add: [ new Date(0), '$ts' ] }
$concat | 連接配接操作符,将給定表達式中的字元串連接配接一起。用法: |
$split | 切割操作符,用于對字元串進行分切。用法: |
$toLower | 用于傳回字元串的小寫形式。用法: |
$toUpper | 用于傳回字元串的大寫形式。用法: |
$substr | 用于傳回子字元串,v3.4+版本不建議使用,應該使用substrBytes或substrCP,v3.4+版本使用的話,相當于substrBytes。用法: |
$substrBytes | 用于根據UTF-8下的位元組位置傳回子字元串(起始位置為0),于v3.4新增。用法: |
$substrCP | 用于根據UTF-8下的Code Point位置傳回子字元串(起始位置為0),于v3.4新增。用法: |
Code Point : (1) Any value in the Unicode codespace; that is, the range of integers from 0 to 10FFFF16. Not all code points are assigned to encoded characters. See code point type. (2) A value, or position, for a character, in any coded character set.
| item - a |
| |
| |
| $split第二個參數必須是一個字元串,不能是數字 |
| "item" |
| |
| "" |
| "ITEM" |
| |
| |
| "bc" |
| "World" |
| "café" |
| "tér" |
| "Error: Invalid range, starting index is a UTF-8 continuation byte." |
| "Error: Invalid range, ending index is in the middle of a UTF-8 character." |
| "壽" |
| |
| |
| "cafét" |
| |
| "ia" |
| "é" |
| "壽司s" |
$dayOfYear | 傳回一年中的一天,值在1和366(閏年)之間。用法: |
$dayOfMonth | 傳回一個月中的一天,值在1和31之間。用法: |
$dayOfWeek | 傳回一周中的一天,值在1(周日)和7(周六)之間。用法: |
$year | 傳回年份,eg:2017。用法: |
$month | 傳回月份,值在1和12之間。用法: |
$week | 傳回周 ,值在0和53之間。用法: |
$hour | 傳回時 ,值在0和23之間。用法: |
$minute | 傳回分 ,值在0和59之間。用法: |
$second | 傳回秒,值在0和60之間(閏秒)。用法: |
$millisecond | 傳回毫秒,值在0和999之間。用法: |
$dateToString | 傳回日期的字元串。用法: |
假如有以下資料:
{ "_id" : 1, "item" : "abc", "price" : 10, "quantity" : 2, "date" : ISODate("2014-01-01T08:15:39.736Z") }
進行如下操作:
db.collection.aggregate(
[
{
$project:
{
year: { $year: "$date" },
month: { $month: "$date" },
day: { $dayOfMonth: "$date" },
hour: { $hour: "$date" },
minutes: { $minute: "$date" },
seconds: { $second: "$date" },
milliseconds: { $millisecond: "$date" },
dayOfYear: { $dayOfYear: "$date" },
dayOfWeek: { $dayOfWeek: "$date" },
week: { $week: "$date" },
yearMonthDayUTC: { $dateToString: { format: "%Y-%m-%d", date: "$date" } },
time: { $dateToString: { format: "%H:%M:%S:%L", date: "$date" } }
}
}
]
)
傳回結果:
{
"_id" : 1,
"year" : 2014,
"month" : 1,
"day" : 1,
"hour" : 8,
"minutes" : 15,
"seconds" : 39,
"milliseconds" : 736,
"dayOfYear" : 1,
"dayOfWeek" : 4,
"week" : 0,
"yearMonthDayUTC" : "2014-01-01",
"time" : "08:15:39:736"
}
$cond | 用法: 或者 v2.6+還支援 |
$ifNull | |
{ "_id" : 1, "name" : "a", score: 80 }
{ "_id" : 2, "name" : "b", score: 69 }
{ "_id" : 3, "name" : "c", score: 53 }
{ "_id" : 3, "name" : null, score: 70 }
db.collection.aggregate(
[
{
$project:
{
_id: 0,
score: 1,
pass:
{
$cond: [ { $gte: [ "$score", 60 ] }, 1, 0 ]
},
description: { $ifNull: [ "$name", "Unspecified" ] }
}
}
]
)
{ "name" : "a", score: 80, pass: 1 }
{ "name" : "b", score: 69, pass: 1 }
{ "name" : "c", score: 53, pass: 0 }
{ "name" : "Unspecified", score: 70, pass: 1 }
總結
本文介紹表達式操作符的分類和常用的表達式操作符的用法,表達式操作符主要作用于$project下,通過使用這些操作符可以對文檔中的字面量進行處理并傳回,進而傳回更多有用的資料。