摘要:當(dāng)在中使用時(shí),累加器是針對(duì)每個(gè)分組使用的當(dāng)在中使用時(shí),累加器則是針對(duì)每個(gè)字面量起作用,具體用法下一篇文章闡述。另外再加以配合表達(dá)式操作符組成的表達(dá)式或者在或中使用累加器能查詢統(tǒng)計(jì)的內(nèi)容會(huì)更加的多樣化。
上篇最后說到管道操作符,本篇文章將詳細(xì)說一下管道操作符。
mongoDB查詢進(jìn)階--聚合管道(一)回顧
什么是管道操作符(Aggregation Pipeline Operators)mongoDB有4類操作符用于文檔的操作,例如find查詢里面會(huì)用到的$gte,$in等。操作符以$開頭,分為查詢操作符,更新操作符,管道操作符,查詢修飾符4大類。其中管道操作符是用于聚合管道中的操作符。
管道操作符的分類管道操作符可以分為三類:
階段操作符(Stage Operators)
表達(dá)式操作符(Expression Operators)
累加器(Accumulators)
此處中文勉強(qiáng)翻譯,以英文為準(zhǔn),歡迎大神給意見,謝謝。
參考MongoDB官網(wǎng):https://docs.mongodb.com/manual/reference/operator/aggregation/#accumulators
階段操作符是使用于db.collection.aggregate方法里面,數(shù)組參數(shù)中的第一層。
db.collection.aggregate( [ { 階段操作符:表述 }, { 階段操作符:表述 }, ... ] )
表達(dá)式操作符主要用于在管道中構(gòu)建表達(dá)式時(shí)使用,使用類似于函數(shù)那樣需要參數(shù),主要用于$project操作符中,用于構(gòu)建表達(dá)式,使用方法一般如下:
方法1:
{: [ , ... ] }
方法2:
{: }
累加器本來只能使用與$groud下,但是版本3.2或以上,部分累加器還能使用于$project。當(dāng)在$group中使用時(shí),累加器是針對(duì)每個(gè)分組使用的;當(dāng)在$project中使用時(shí),累加器則是針對(duì)每個(gè)字面量起作用,具體用法下一篇文章闡述。
常用階段操作符由于操作符比較多,本篇文章先說第一類階段操作符,后面兩類在下一篇再說。
操作符 | 簡(jiǎn)述 |
---|---|
$match | 匹配操作符,用于對(duì)文檔集合進(jìn)行篩選 |
$project | 投射操作符,用于重構(gòu)每一個(gè)文檔的字段,可以提取字段,重命名字段,甚至可以對(duì)原有字段進(jìn)行操作后新增字段 |
$sort | 排序操作符,用于根據(jù)一個(gè)或多個(gè)字段對(duì)文檔進(jìn)行排序 |
$limit | 限制操作符,用于限制返回文檔的數(shù)量 |
$skip | 跳過操作符,用于跳過指定數(shù)量的文檔 |
$count | 統(tǒng)計(jì)操作符,用于統(tǒng)計(jì)文檔的數(shù)量 |
$group | 分組操作符,用于對(duì)文檔集合進(jìn)行分組 |
$unwind | 拆分操作符,用于將數(shù)組中的每一個(gè)值拆分為多帶帶的文檔 |
$lookup | 連接操作符,用于連接同一個(gè)數(shù)據(jù)庫(kù)中另一個(gè)集合,并獲取指定的文檔,類似于populate |
更多操作符介紹詳見官網(wǎng):https://docs.mongodb.com/manual/reference/operator/aggregation/
階段操作符詳解假設(shè)有一個(gè)保存用戶的集合Users,一個(gè)文章的集合Articles,數(shù)據(jù)大致如下:
users:
[ { name: "John", age: 16, sex: male, city: guangzhou, _id: 1, ...}, { name: "Rose", age: 18, sex: female, city: beijing, _id: 2, ...}, { name: "Jack", age: 29, sex: male, city: guangzhou, _id: 3, ...}, { name: "Allen", age: 18, sex: female, city: beijing, _id: 4, ...}, { name: "Cruz", age: 22, sex: male, city: guangzhou, _id: 5, ...}, { name: "Peter", age: 18, sex: male, city: guangzhou, _id: 6, ...}, { name: "Kelly", age: 23, sex: female, city: shanghai, _id: 7, ...}, ... ]
articles:
[ { title: "this is article A", author: "John", _id: 1, ... }, { title: "this is article B", author: "Jack", _id: 2, ... }, { title: "this is article C", author: "Rose", _id: 3, ... }, { title: "this is article D", author: "John", _id: 4, ... }, { title: "this is article E", author: "John", _id: 5, ... }, ... ]$match 匹配操作符
用于重構(gòu)每一個(gè)文檔的字段,可以提取字段,重命名字段,甚至可以對(duì)原有字段進(jìn)行操作后新增字段
{ $match: {} }
查詢用戶年齡是18歲的用戶
db.users.aggregate([{ $match : { age : "18" } }]);$project 投射操作符
用于對(duì)文檔集合進(jìn)行篩選
{ $project: {} }
specification的規(guī)則
規(guī)則 | 描述 |
---|---|
<字段名>: 1 or true | 選擇需要返回什么字段 |
_id: 0 or false | 不返回_id(默認(rèn)返回) |
<字段名>: 表達(dá)式 | 使用表達(dá)式,可以用于重命名字段,或?qū)ζ渲颠M(jìn)行操作,或新增字段 |
<字段名>: 0 or false | 選擇需要不返回什么字段,注意:當(dāng)使用這種用法時(shí),就不要用上面的方法 |
用戶集合投射用戶姓名
不返回_id
db.users.aggregate([{ $project : { name: 1 } }]);
將_id重命名為userId
不返回_id_
db.users.aggregate([{ $project : { ueserId: "$_id", _id: 0 } }]);
返回新字段username,并使用表達(dá)式讓它的值為name的大寫。
db.users.aggregate([ { $project : { name: 1, username: { $toUpper: "$name" }, _id: 0 } } ]);
$sort 排序操作符關(guān)于管道表達(dá)式:最簡(jiǎn)單的“$project”表達(dá)式是包含和排除字段(如: { name: 1 }),以及字段名稱$fieldname(如: { userId: "$_id" })。除此以外,還可以使用表達(dá)式操作符(如: $toUpper)構(gòu)成更豐富的表達(dá)式,將多個(gè)字面量和變量組合在一起使用,得到更多有意思的值,更多表達(dá)式操作符的說明及使用在另外的篇章中詳細(xì)闡述。
用于根據(jù)一個(gè)或多個(gè)字段對(duì)文檔進(jìn)行排序
{ $sort: {: , : ... } }
users集合按照年齡age從低到高排序
db.users.aggregate([{ $sort : { age: 1 } }]);$limit 限制操作符
用于限制返回文檔的數(shù)量
{ $limit:}
返回5篇article
db.articles.aggregate({ $limit : 3 });$skip 跳過操作符
用于跳過指定數(shù)量的文檔
{ $skip:}
跳過1個(gè)文檔
db.users.aggregate([{ $skip : 1 }]);$count 統(tǒng)計(jì)操作符
用于統(tǒng)計(jì)文檔的數(shù)量
{ $count:}
string是統(tǒng)計(jì)之后輸出統(tǒng)計(jì)結(jié)果的字段名
統(tǒng)計(jì)文章的總數(shù),以totalArticle返回
db.articles.aggregate([{ totalArticle : 1 }]);$group 分組操作符
用于對(duì)文檔集合進(jìn)行分組
{ $group: { _id:, : { : }, ... } }
_id是必須的,用作分組的依據(jù)條件
將用戶(users)按性別(sex)分組
db.users.aggregate([{ $group : { _id: "$sex" } }]);
返回結(jié)果:
[ { _id: "male" }, { _id: "female" } ]
將用戶(users)按性別(sex)分組
分組后使用計(jì)算各自性別的平均年齡
統(tǒng)計(jì)不同的性別的人數(shù),并以count返回
db.users.aggregate([ { $group : { _id: "$sex", avgAge: { $avg: "$age" }, conut: { $sum: 1 } } } ]);
返回結(jié)果:
[ { _id: "male", avgAge: <男性平均年齡>, count: <男性人數(shù)> }, { _id: "female", avgAge: <女性平均年齡>, count: <女性人數(shù)> } ]
$unwind 拆分操作符此處用到的表達(dá)式 { $avg: "$age" } 用于求平均年齡,$avg是求均值的操作符,$sum用于匯總, 都只能在$group中使用的累加器,mongoDB3.2以上版本則還可以在$project中使用,詳細(xì)會(huì)在另外的篇章中闡述。
用于將數(shù)組中的每一個(gè)值拆分為多帶帶的文檔
{ $unwind:}
增加icludeArrayIndex,preserveNullAndEmptyArrays兩個(gè)可選配置
{ $unwind: { path:, includeArrayIndex: , preserveNullAndEmptyArrays: } }
字段 | 類型 | 描述 |
---|---|---|
path | string | 必填,數(shù)組的字段名,指定需要拆分的字段 |
includeArrayIndex | string | 可選,定義返回的字段名,返回的值是拆分前值在原數(shù)組的位置 |
preserveNullAndEmptyArrays | boolean | 可選,配置在path的值為空或缺失的情況下是否拆分, 默認(rèn)false |
假設(shè)articles文檔集合是這樣:
{ title: "this is article A", author: "John", _id: 1, comments: ["a", "b", "c"]}
db.articles.aggregate([{ $unwind: "$comments" }]);
結(jié)果:
[ { title: "this is article A", author: "John", _id: 1, comments: "a"}, { title: "this is article A", author: "John", _id: 1, comments: "b"}, { title: "this is article A", author: "John", _id: 1, comments: "c"}, ]
假設(shè)articles文檔集合是這樣:
[ { title: "this is article A", author: "John", _id: 1, comments: ["a", "b", "c"] } { title: "this is article B", author: "Jack", _id: 2 }, { title: "this is article C", author: "Amy", _id: 3, comments: [] }, { title: "this is article D", author: "Lam", _id: 4, comments: null }, ]
操作:
db.articles.aggregate([ { $unwind: { path: "$comments", includeArrayIndex: "arrayIndex", } } ]);
結(jié)果:
[ { title: "this is article A", author: "John", _id: 1, comments: "a", arrayIndex: NumberLong(0) }, { title: "this is article A", author: "John", _id: 1, comments: "b", arrayIndex: NumberLong(1) }, { title: "this is article A", author: "John", _id: 1, comments: "c", arrayIndex: NumberLong(2) }, ]
操作:
db.articles.aggregate([ { $unwind: { path: "$comments", preserveNullAndEmptyArrays: true, } } ]);
結(jié)果:
[ { title: "this is article A", author: "John", _id: 1, comments: "a" }, { title: "this is article A", author: "John", _id: 1, comments: "b" }, { title: "this is article A", author: "John", _id: 1, comments: "c" }, { title: "this is article B", author: "Jack", _id: 2 }, { title: "this is article C", author: "Amy", _id: 3 }, { title: "this is article C", author: "Amy", _id: 3, comments: null } ]$lookup 連接操作符
用于連接同一個(gè)數(shù)據(jù)庫(kù)中另一個(gè)集合,并獲取指定的文檔,類似于populate
{ $lookup: { from:, localField: , foreignField: , as:
字段 | 描述 |
---|---|
from | 需要關(guān)聯(lián)的集合名 |
localField | 本集合中需要查找的字段 |
foreignField | 另外一個(gè)集合中需要關(guān)聯(lián)的字段 |
as | 輸出的字段名 |
ariticles中的author關(guān)聯(lián)到user表
authoer字段返回詳細(xì)的用戶的信息
db.articles.aggregate([ { $lookup: { from: "users", localField: "author", foreignField: "name", as: "author" } } ])
結(jié)果:
[ { title: "this is article A", author: { name: "John", age: 16, sex: male, city: guangzhou, _id: 1, ... }, _id: 1, ... }, { title: "this is article B", author: { name: "Jack", age: 29, sex: male, city: guangzhou, _id: 3, ... }, _id: 2, ... }, { title: "this is article C", author: { name: "Rose", age: 18, sex: male, city: beijing, _id: 2, ... }, _id: 3, ... }, { title: "this is article D", author: { name: "John", age: 16, sex: male, city: guangzhou, _id: 1, ... }, _id: 4, ... }, { title: "this is article E", author: { name: "John", age: 16, sex: male, city: guangzhou, _id: 1, ... }, _id: 5, ... }, ... ]綜合示例
找出發(fā)表文章最多的5位作者,按發(fā)表文章排序,顯示他的發(fā)表文章的總次數(shù),和他自己的信息
文章按照作者分組,統(tǒng)計(jì)次數(shù)
按照次數(shù)從高到低排序
截取頭5名
關(guān)聯(lián)用戶信息
不輸出文章_id
db.articles.aggregate([ { $group: { _id: "$author", count: { $sum: 1 }, } }, { $sort: { count: -1 } }, { $skip: 5 }, { $lookup: { from: "users", localField: "author", foreignField: "name", as: "author" } }, { $project: { _id: 0, } } ])總結(jié)
本文介紹了幾個(gè)使用聚合管道查詢時(shí)常用的管道操作符的用法,熟練地綜合使用以上操作符可以對(duì)數(shù)據(jù)進(jìn)行多樣的處理,組合,統(tǒng)計(jì),得出多樣化的數(shù)據(jù)。另外再加以配合表達(dá)式操作符(Expression Operators)組成的表達(dá)式, 或者在$project或$group中使用累加器(Accumulators)能查詢統(tǒng)計(jì)的內(nèi)容會(huì)更加的多樣化。
感謝閱讀~
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/84867.html
摘要:當(dāng)在中使用時(shí),累加器是針對(duì)每個(gè)分組使用的當(dāng)在中使用時(shí),累加器則是針對(duì)每個(gè)字面量起作用,具體用法下一篇文章闡述。另外再加以配合表達(dá)式操作符組成的表達(dá)式或者在或中使用累加器能查詢統(tǒng)計(jì)的內(nèi)容會(huì)更加的多樣化。 上篇最后說到管道操作符,本篇文章將詳細(xì)說一下管道操作符。 mongoDB查詢進(jìn)階--聚合管道(一)回顧 什么是管道操作符(Aggregation Pipeline Operators) ...
摘要:累加器累加器本來只能使用與下,但是版本或以上,部分累加器還能使用于。當(dāng)在中使用時(shí),累加器是針對(duì)每個(gè)分組使用的當(dāng)在中使用時(shí),累加器則是針對(duì)每個(gè)字面量起作用。 回顧 相關(guān)文章回顧 mongoDB查詢進(jìn)階--聚合管道(一)回顧mongoDB查詢進(jìn)階--聚合管道(二)回顧mongoDB查詢進(jìn)階--聚合管道(三)回顧 管道操作符的分類 管道操作符可以分為三類: 階段操作符(Stage Oper...
摘要:累加器累加器本來只能使用與下,但是版本或以上,部分累加器還能使用于。當(dāng)在中使用時(shí),累加器是針對(duì)每個(gè)分組使用的當(dāng)在中使用時(shí),累加器則是針對(duì)每個(gè)字面量起作用。 回顧 相關(guān)文章回顧 mongoDB查詢進(jìn)階--聚合管道(一)回顧mongoDB查詢進(jìn)階--聚合管道(二)回顧mongoDB查詢進(jìn)階--聚合管道(三)回顧 管道操作符的分類 管道操作符可以分為三類: 階段操作符(Stage Oper...
摘要:用法取反操作符,返回表達(dá)式中取反后的布爾值。用法示例假設(shè)有一個(gè)關(guān)于考試成績(jī)的集合操作如下返回結(jié)果數(shù)學(xué)操作符操作符簡(jiǎn)述求絕對(duì)值操作符,于版新加入。用法進(jìn)一法取整操作符,取于版新加入。用法切割操作符,用于對(duì)字符串進(jìn)行分切。 回顧 相關(guān)文章回顧 mongoDB查詢進(jìn)階--聚合管道(一)回顧mongoDB查詢進(jìn)階--聚合管道(二)回顧 管道操作符的分類 管道操作符可以分為三類: 階段操作符(...
摘要:用法取反操作符,返回表達(dá)式中取反后的布爾值。用法示例假設(shè)有一個(gè)關(guān)于考試成績(jī)的集合操作如下返回結(jié)果數(shù)學(xué)操作符操作符簡(jiǎn)述求絕對(duì)值操作符,于版新加入。用法進(jìn)一法取整操作符,取于版新加入。用法切割操作符,用于對(duì)字符串進(jìn)行分切。 回顧 相關(guān)文章回顧 mongoDB查詢進(jìn)階--聚合管道(一)回顧mongoDB查詢進(jìn)階--聚合管道(二)回顧 管道操作符的分類 管道操作符可以分為三類: 階段操作符(...
閱讀 701·2021-11-23 09:51
閱讀 3622·2021-11-15 11:38
閱讀 975·2021-10-14 09:42
閱讀 3216·2021-09-29 09:35
閱讀 2149·2021-09-03 10:33
閱讀 790·2021-07-30 16:33
閱讀 1582·2019-08-30 15:55
閱讀 1867·2019-08-30 14:04