group
语法
db.collection.group({
key:{
field:
1},
initial:{
count:
0},
cond:{},
reduce: function ( curr, result ) { },
keyf:
function(doc){},
finalize:function(result) {}
})
除了分组的key字段外,就只返回有result参数的回调函数中的操作的属性字段;
实例
# 表结构如下
{
_id:
ObjectId(
"5085a95c8fada716c89d0021"),
ord_dt:
ISODate(
"2012-07-01T04:00:00Z"),
ship_dt:
ISODate(
"2012-07-02T04:00:00Z"),
item: { sku:
"abc123",
price:
1.99,
uom:
"pcs",
qty:
25 }
}
SELECT ord_dt, item_sku
FROM orders
WHERE ord_dt >
'01/01/2012'
GROUP BY ord_dt, item_sku
↓↓↓↓
db.orders.group(
{
key: { ord_dt:
1,
'item.sku':
1 },
cond: { ord_dt: { $gt:
new Date(
'01/01/2012' ) } },
reduce:
function ( curr, result ) { },
initial: { }
}
)
SELECT ord_dt, item_sku, SUM(item_qty)
as total
FROM orders
WHERE ord_dt >
'01/01/2012'
GROUP BY ord_dt, item_sku
↓↓↓↓
db.orders.group(
{
key: { ord_dt:
1,
'item.sku':
1 },
cond: { ord_dt: { $gt:
new Date(
'01/01/2012' ) } },
reduce:
function( curr, result ) {
result.total += curr.item.qty;
},
initial: { total :
0 }
}
)
db.orders.group(
{
keyf:
function(doc) {
return { day_of_week: doc.ord_dt.getDay() };
},
cond: { ord_dt: { $gt:
new Date(
'01/01/2012' ) } },
reduce:
function( curr, result ) {
result.total += curr.item.qty;
result.count++;
},
initial: { total :
0, count:
0 },
finalize:
function(result) {
var weekdays = [
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday"
];
result.day_of_week = weekdays[result.day_of_week];
result.avg = Math.round(result.total / result.count);
}
}
)
[
{
"day_of_week" :
"Sunday",
"total" :
70,
"count" :
4,
"avg" :
18 },
{
"day_of_week" :
"Friday",
"total" :
110,
"count" :
6,
"avg" :
18 },
{
"day_of_week" :
"Tuesday",
"total" :
70,
"count" :
3,
"avg" :
23 }
]
工作中用到的实例
{
key:{cat_id:
1},
cond:{},
reduce:
function(curr , result) {
if(curr.shop_price > result.max) {
result.max = curr.shop_price;
}
},
initial:{max:
0}
}
{
key:{cat_id:
1},
cond:{},
reduce:
function(curr , result) {
result.cnt +=
1;
result.sum += curr.shop_price;
},
initial:{sum:
0,cnt:
0},
finalize:
function(result) {
result.avg = result.sum/result.cnt;
}
}
group其实略微有点鸡肋,因为既然用到了mongodb,那复制集和分片是避无可免的,而group是不支持分片的运算
Aggregation
聚合管道是一个基于数据处理管道概念的框架。通过使用一个多阶段的管道,将一组文档转换为最终的聚合结果。
语法
参考手册: http://docs.mongoing.com/manual-zh/core/aggregation-pipeline.html
db.collection.aggregate(pipeline, options);
pipeline
Array
$project
$match
$sort
$limit
$skip
$unwind
$group: { _id: <expression>, <field1>: { <accumulator1> : <expression1> }, ...
$geoNear
$out
实例
Example1:unwind
> db.test.insert({
"_id" : 1,
"item" :
"ABC1", sizes: [
"S",
"M",
"L"] });
WriteResult({
"nInserted" : 1 })
> db.test.aggregate( [ {
$unwind :
"$sizes" } ] )
{
"_id" : 1,
"item" :
"ABC1",
"sizes" :
"S" }
{
"_id" : 1,
"item" :
"ABC1",
"sizes" :
"M" }
{
"_id" : 1,
"item" :
"ABC1",
"sizes" :
"L" }
db.test.insert({
"_id" : 2,
"item" :
"ABC1", sizes: [
"S",
"M",
"L",[
"XXL",
'XL']] });
WriteResult({
"nInserted" : 1 })
> db.test.aggregate( [ {
$unwind :
"$sizes" } ] )
{
"_id" : 1,
"item" :
"ABC1",
"sizes" :
"S" }
{
"_id" : 1,
"item" :
"ABC1",
"sizes" :
"M" }
{
"_id" : 1,
"item" :
"ABC1",
"sizes" :
"L" }
{
"_id" : 2,
"item" :
"ABC1",
"sizes" :
"S" }
{
"_id" : 2,
"item" :
"ABC1",
"sizes" :
"M" }
{
"_id" : 2,
"item" :
"ABC1",
"sizes" :
"L" }
{
"_id" : 2,
"item" :
"ABC1",
"sizes" : [
"XXL",
"XL" ] }
Example2
{
"_id" : 1,
"item" :
"abc",
"price" : 10,
"quantity" : 2,
"date" : ISODate(
"2014-03-01T08:00:00Z") }
{
"_id" : 2,
"item" :
"jkl",
"price" : 20,
"quantity" : 1,
"date" : ISODate(
"2014-03-01T09:00:00Z") }
{
"_id" : 3,
"item" :
"xyz",
"price" : 5,
"quantity" : 10,
"date" : ISODate(
"2014-03-15T09:00:00Z") }
{
"_id" : 4,
"item" :
"xyz",
"price" : 5,
"quantity" : 20,
"date" : ISODate(
"2014-04-04T11:21:39.736Z") }
{
"_id" : 5,
"item" :
"abc",
"price" : 10,
"quantity" : 10,
"date" : ISODate(
"2014-04-04T21:23:13.331Z") }
db.sales.aggregate([
{
$project:{item:1,price:1,quantity:1}
},
{
$group:{
_id:
"$item",
quantityCount:{
$sum:
'$quantity'},
priceTotal:{
$sum:
'$price'}
}
},
{
$sort:{
quantityCount:1
}
},
{
$skip: 2
},
{
$limit:1
},
{
$out:
'result'
}
])
db.sales.aggregate(
[
{
$group : {
_id : { month: {
$month:
"$date" }, day: {
$dayOfMonth:
"$date" }, year: {
$year:
"$date" } },
totalPrice: {
$sum: {
$multiply: [
"$price",
"$quantity" ] } },
averageQuantity: {
$avg:
"$quantity" },
count: {
$sum: 1 }
}
}
]
)
{
"_id" : {
"month" : 3,
"day" : 15,
"year" : 2014 },
"totalPrice" : 50,
"averageQuantity" : 10,
"count" : 1 }
{
"_id" : {
"month" : 4,
"day" : 4,
"year" : 2014 },
"totalPrice" : 200,
"averageQuantity" : 15,
"count" : 2 }
{
"_id" : {
"month" : 3,
"day" : 1,
"year" : 2014 },
"totalPrice" : 40,
"averageQuantity" : 1.5,
"count" : 2 }
db.sales.aggregate(
[
{
$group:
{
_id: { day: {
$dayOfYear:
"$date"}, year: {
$year:
"$date" } },
itemsSold: {
$push: { item:
"$item", quantity:
"$quantity" } }
}
}
]
)
{
"_id" : {
"day" : 46,
"year" : 2014 },
"itemsSold" : [
{
"item" :
"abc",
"quantity" : 10 },
{
"item" :
"xyz",
"quantity" : 10 },
{
"item" :
"xyz",
"quantity" : 5 },
{
"item" :
"xyz",
"quantity" : 10 }
]
}
{
"_id" : {
"day" : 34,
"year" : 2014 },
"itemsSold" : [
{
"item" :
"jkl",
"quantity" : 1 },
{
"item" :
"xyz",
"quantity" : 5 }
]
}
{
"_id" : {
"day" : 1,
"year" : 2014 },
"itemsSold" : [ {
"item" :
"abc",
"quantity" : 2 } ]
}
db.sales.aggregate(
[
{
$group:
{
_id: { day: {
$dayOfYear:
"$date"}, year: {
$year:
"$date" } },
itemsSold: {
$addToSet:
"$item" }
}
}
]
)
{
"_id" : {
"day" : 46,
"year" : 2014 },
"itemsSold" : [
"xyz",
"abc" ] }
{
"_id" : {
"day" : 34,
"year" : 2014 },
"itemsSold" : [
"xyz",
"jkl" ] }
{
"_id" : {
"day" : 1,
"year" : 2014 },
"itemsSold" : [
"abc" ] }
db.sales.aggregate(
[
{
$sort: { item: 1, date: 1 } },
{
$group:
{
_id:
"$item",
firstSalesDate: {
$first:
"$date" }
}
}
]
)
{
"_id" :
"xyz",
"firstSalesDate" : ISODate(
"2014-02-03T09:05:00Z") }
{
"_id" :
"jkl",
"firstSalesDate" : ISODate(
"2014-02-03T09:00:00Z") }
{
"_id" :
"abc",
"firstSalesDate" : ISODate(
"2014-01-01T08:00:00Z") }
Example3
db.sales.aggregate(
[
{
$group : {
_id : null, # 如果为null,就统计出全部
totalPrice: { $sum: { $multiply: [
"$price",
"$quantity" ] } },
averageQuantity: { $avg:
"$quantity" },
count: { $sum:
1 }
}
}
]
)
Example4
{
"_id" : 8751,
"title" :
"The Banquet",
"author" :
"Dante",
"copies" : 2 }
{
"_id" : 8752,
"title" :
"Divine Comedy",
"author" :
"Dante",
"copies" : 1 }
{
"_id" : 8645,
"title" :
"Eclogues",
"author" :
"Dante",
"copies" : 2 }
{
"_id" : 7000,
"title" :
"The Odyssey",
"author" :
"Homer",
"copies" : 10 }
{
"_id" : 7020,
"title" :
"Iliad",
"author" :
"Homer",
"copies" : 10 }
db.books.aggregate(
[
{
$group : { _id :
"$author", books: {
$push:
"$title" } } }
]
)
{
"_id" :
"Homer",
"books" : [
"The Odyssey",
"Iliad" ] }
{
"_id" :
"Dante",
"books" : [
"The Banquet",
"Divine Comedy",
"Eclogues" ] }
db.books.aggregate(
[
{
$group : { _id :
"$author", books: {
$push:
"$$ROOT" } } }
]
)
{
"_id" :
"Homer",
"books" :
[
{
"_id" : 7000,
"title" :
"The Odyssey",
"author" :
"Homer",
"copies" : 10 },
{
"_id" : 7020,
"title" :
"Iliad",
"author" :
"Homer",
"copies" : 10 }
]
}
{
"_id" :
"Dante",
"books" :
[
{
"_id" : 8751,
"title" :
"The Banquet",
"author" :
"Dante",
"copies" : 2 },
{
"_id" : 8752,
"title" :
"Divine Comedy",
"author" :
"Dante",
"copies" : 1 },
{
"_id" : 8645,
"title" :
"Eclogues",
"author" :
"Dante",
"copies" : 2 }
]
}
邮政编码数据集的聚合实例: http://docs.mongoing.com/manual-zh/tutorial/aggregation-zip-code-data-set.html
对用户爱好数据做聚合实例:
http://docs.mongoing.com/manual-zh/tutorial/aggregation-with-user-preference-data.html
转载请注明原文地址: https://ju.6miu.com/read-668639.html