aggregate()
db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION);
數據使用菜鳥教程的數據啦🤪🤪
/* 1 */
{
"_id" : ObjectId("5e86e29788e64443e448dfc0"),
"title" : "MongoDB Overview",
"description" : "MongoDB is no sql database",
"by_user" : "runoob.com",
"url" : "http://www.runoob.com",
"tags" : [
"mongodb",
"database",
"NoSQL"
],
"likes" : 100
}
/* 2 */
{
"_id" : ObjectId("5e86e2ad88e64443e448dfd2"),
"title" : "NoSQL Overview",
"description" : "No sql database is very fast",
"by_user" : "runoob.com",
"url" : "http://www.runoob.com",
"tags" : [
"mongodb",
"database",
"NoSQL"
],
"likes" : 10
}
/* 3 */
{
"_id" : ObjectId("5e86e2bc88e64443e448dfd7"),
"title" : "Neo4j Overview",
"description" : "Neo4j is no sql database",
"by_user" : "Neo4j",
"url" : "http://www.neo4j.com",
"tags" : [
"neo4j",
"database",
"NoSQL"
],
"likes" : 750
}
操作符 | 含義 |
---|---|
$group | 將collection中的document分組,可用於統計結果 |
$match | 過濾數據,只輸出符合結果的文檔 |
$project | 修改輸入文檔的結構(例如重命名,增加、刪除字段,創建結算結果等) |
$sort | 將結果進行排序後輸出 |
$limit | 限制管道輸出的結果個數 |
$skip | 跳過制定數量的結果,並且返回剩下的結果 |
$unwind | 將數組類型的字段進行拆分 |
操作符 | 含義 | 實例 |
---|---|---|
$sum | 計算總和,{$sum : 1}表示返回總和×1的值(即總和的數量),使用{$sum : '$制定字段' }也能直接獲取制定字段的值的總和 |
db.collection.aggregate([{$group : {_id : "$by_user", content_sum : {$sum : "$likes"}}}]) |
$avg | 平均值 | db.collection.aggregate([{$group : {_id : "$by_user", content_sum : {$avg : "$likes"}}}]) |
$min | 獲取集合中所有文檔對應值得最小值 | db.collection.aggregate([{$group : {_id : "$by_user", content_sum : {$min : "$likes"}}}]) |
$max | 獲取集合中所有文檔對應值得最大值 | db.collection.aggregate([{$group : {_id : "$by_user", content_sum : {$max : "$likes"}}}]) |
$push | 在結果文檔中插入值到一個數組中 | db.collection.aggregate([{$group : {_id : "$by_user", url : {$push : "$url"}}}]) |
$addToSet | 在結果文檔中插入值到一個數組中,但不創建副本 | db.collection.aggregate([{$group : {_id : "$by_user", url : {$addToSet : "$url"}}}]) |
$first | 根據資源文檔的排序獲取第一個文檔數據 | db.collection.aggregate([{$group : {_id : "$by_user", url : {$first : "$url"}}}]) |
$last | 根據資源文檔的排序獲取最後一個文檔數據 | db.collection.aggregate([{$group : {_id : "$by_user", url : {$last : "$url"}}}]) |
-
$group
-
簡單闡述
//將document分組,用作統計結果 db.collection.aggregate([ // aggregate方法接收的是一個數組 { $group: { // _id字段表示要基於哪個字段來進行分組(即制定字段值相同的爲一組) // $by_user表示要基於$by_user字段來進行分組 _id: '$by_user', // content_sum字段的值$sum: 1表示的是獲取滿足by_user字段相同的這一組的數量乘以後面給定的值(本例爲1,那麼就是同組的數量)。 content_sum: {$sum: 1} } } ])
-
具體案例
通過以上集合計算每個作者所寫的文章數(通過字段
by_user
字段對數據進行分組,並計算by_user
字段相同值的總和),使用aggregate()
計算結果如下:router.get('/getInfo',async(req, res)=>{ let data=await Content.aggregate([ { $group:{ _id:'$by_user', content_sum:{$sum:1} } } ]) res.json({data}) })
-
-
$match
獲取
likes
的值在50-200
之間的數據:router.get('/getInfo', async (req, res) => { let data = await Content.aggregate([{ $match: { likes: { $gt: 50, $lte: 200 } } }, { $group: { _id: '$_id', content_sum: { $sum: 1 } } } ]) res.json({ data }) })
從圖中可以看出
likes
的值在50-200
之間的數據只有1條,現在我們只知道這條數據的_id,如果想知道這條數據的具體信息時應該如何操作呢❓上面的表格中提到$project
修改輸入文檔的結構(例如重命名,增加、刪除字段,創建結算結果等),所以一起來看看吧👇👇👇 -
$project
router.get('/getInfo', async (req, res) => { let data = await Content.aggregate([ { $match: { likes: { $gt: 50, $lte: 200 } } }, { //以下的值可以寫$+字段,也可以使用0 和1來表示,若要顯示字段則爲1,否則爲0 //$project:{_id:'$_id',title:"$title",description:"$description",by_user:"$by_user",url:'$ulr',tags:'$tags',likes:'$likes'} $project:{_id:1,title:1,description:1,by_user:1,url:1,tags:1,likes:1} } ]) res.json({ data }) })
-
以上3個操作符的綜合使用
如果想拿到所有
likes>=10
的document的by_user
字段可以把管道搭配起來用:router.get('/getInfo', async (req, res) => { let data = await Content.aggregate([{ $match: { likes: { $gt: 10 } } }, // 注意$project與$group的順序,換位置後數據爲空 { $project: { _id: 0, //_id不顯示 by_user: 1 //by_user顯示 } }, { $group: { _id: null, gameName: { $push: '$by_user' } } } ]) res.json({ data }) })
-
$sort
-
根據
likes
進行降序排序router.get('/getInfo', async (req, res) => { let data = await Content.aggregate([ { $project: { _id: 1, by_user: 1, title: 1, title: 1, description: 1, url: 1, tags: 1, likes: 1 } }, { $sort: { likes: -1 } }, ]) res.json({ data }) })
-
根據
likes
進行升序排序router.get('/getInfo', async (req, res) => { let data = await Content.aggregate([ { $project: { _id: 1, by_user: 1, title: 1, title: 1, description: 1, url: 1, tags: 1, likes: 1 } }, { $sort: { likes: 1 } }, ]) res.json({ data }) })
-
-
$limit and $skip
router.get('/getInfo', async (req, res) => { let data = await Content.aggregate([ { $project: { _id: 1, by_user: 1, title: 1, title: 1, description: 1, url: 1, tags: 1, likes: 1 } }, { $sort: { likes: 1 } }, { $skip:1 }, { $limit:1 } ]); res.json({ data }) })
-
$unwind
$unwind管道以document中的數組類型的字段進行拆分,每條包含數組中的一個值。
比如拆分
likes:10
這條數據,先來看看整體數據信息吧:{ "_id" : ObjectId("5e86e2ad88e64443e448dfd2"), "title" : "NoSQL Overview", "description" : "No sql database is very fast", "by_user" : "runoob.com", "url" : "http://www.runoob.com", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 10 }
在
tags
數組中有3條數據,所以拆分後會顯示3條數據,看看具體實現吧:router.get('/getInfo', async (req, res) => { let data = await Content.aggregate([ { $match: { likes: 10 } }, { $unwind:'$tags' }, { $project: { _id: 1, by_user: 1, title: 1, title: 1, description: 1, url: 1, tags: 1, likes: 1 } }, ]) res.json({ data }) })