#脚本准备
var tags = ["nosql","mongodb","document","developer","popular"];
var types = ["technology","sociality","travel","novel","literature"];
var books=[];
for(var i=0;i<50;i++){
var typeIdx = Math.floor(Math.random()*types.length);
var tagIdx = Math.floor(Math.random()*tags.length);
var tagIdx2 = Math.floor(Math.random()*tags.length);
var favCount = Math.floor(Math.random()*100);
var username = "xx00"+Math.floor(Math.random()*10);
var age = 20 + Math.floor(Math.random()*15);
var book = {
title: "book-"+i,
type: types[typeIdx],
tag: [tags[tagIdx],tags[tagIdx2]],
favCount: favCount,
author: {name:username,age:age}
};
books.push(book)
}
db.books.insertMany(books);
#投影操作, 将原始字段投影成指定名称, 如将集合中的 title 投影成 name
db.books.aggregate([{$project:{name:"$title"}}])
#$project 可以灵活控制输出文档的格式,也可以剔除不需要的字段
db.books.aggregate([{$project:{name:"$title",_id:0,type:1,author:1}}])
#从嵌套文档中排除字段
db.books.aggregate([ {$project:{name:"$title",_id:0,type:1,"author.name":1}} ])
或者
db.books.aggregate([ {$project:{name:"$title",_id:0,type:1,author:{name:1}}} ])
#$match用于对文档进行筛选,之后可以在得到的文档子集上做聚合,$match可以使用除了地理空 间之
外的所有常规查询操作符,在实际应用中尽可能将$match放在管道的前面位置。这样有两个好处:一是
可以快速将不需要的文档过滤掉,以减少管道的工作量;二是如果再投射和分组之前执行$match,查询
可以使用索引。
db.books.aggregate([{$match:{type:"novel"}}])
#$count 计数并返回与查询匹配的结果数
db.books.aggregate([ {$match:{type:"novel"}}, {$count: "type_count"} ])
$match阶段筛选出type匹配technology的文档,并传到下一阶段;
$count阶段返回聚合管道中剩余文档的计数,并将该值分配给type_count
#book的数量,收藏总数和平均值
db.books.aggregate([ {$group:{_id:null,count:{$sum:1},pop:{$sum:"$favCount"},avg: {$avg:"$favCount"}}} ])
#统计每个作者的book收藏总数
db.books.aggregate([ {$group:{_id:"$author.name",pop:{$sum:"$favCount"}}} ])
#统计每个作者的每本book的收藏数
db.books.aggregate([ {$group:{_id:{name:"$author.name",title:"$title"},pop:{$sum:"$favCount"}}} ])
#每个作者的book的type合集
db.books.aggregate([ {$group:{_id:"$author.name",types:{$addToSet:"$type"}}} ])
#姓名为xx006的作者的book的tag数组拆分为多个文档
db.books.aggregate([ {$match:{"author.name":"xx006"}}, {$unwind:"$tag"} ])
#每个作者的book的tag合集
db.books.aggregate([ {$unwind:"$tag"}, {$group:{_id:"$author.name",types:{$addToSet:"$tag"}}} ])
#插入数据
db.books.insert([ { "title" : "book-51", "type" : "technology", "favCount" : 11, "tag":[], "author" : { "name" : "fox", "age" : 28 } },{ "title" : "book-52", "type" : "technology", "favCount" : 15, "author" : { "name" : "fox", "age" : 28 } },{ "title" : "book-53", "type" : "technology", "tag" : [ "nosql", "document" ],"favCount" : 20, "author" : { "name" : "fox", "age" : 28 } }])
#测试,刚才插入数据
# 使用includeArrayIndex选项来输出数组元素的数组索引
db.books.aggregate([ {$match:{"author.name":"fox"}}, {$unwind:{path:"$tag", includeArrayIndex: "arrayIndex"}} ])
# 使用preserveNullAndEmptyArrays选项在输出中包含缺少size字段,null或空数组的文档
db.books.aggregate([ {$match:{"author.name":"fox"}}, {$unwind:{path:"$tag", preserveNullAndEmptyArrays: true}} ])
#统计每个分类的book文档数量
db.books.aggregate([
{$group:{_id:"$type",total:{$sum:1}}},
{$sort:{total:-1}}
])
#
db.books.aggregate([{
$bucket:{
groupBy:"$favCount",
boundaries:[0,10,60,80,100],
default:"other",
output:{"count":{$sum:1}}
}
}])
#插入数据脚本
var orders = new Array();
var shipping = new Array();
var addresses = [“广西省玉林市”, “湖南省岳阳市”, “湖北省荆州市”, “甘肃省兰州市”, “吉林省松原市”, “江西省景德镇”, “辽宁省沈阳市”, “福建省厦门市”, “广东省广州市”, “北京市朝阳区”];
for (var i = 10000; i < 20000; i++) {
var orderNo = i + Math.random().toString().substr(2, 5);
orders[i] = {
orderNo: orderNo,
userId: i,
price: Math.round(Math.random() *10000) / 100,
qty: Math.floor(Math.random() * 10) + 1,
orderTime: new Date(new Date().setSeconds(Math.floor(Math.random() * 10000)))
};
var address = addresses[Math.floor(Math.random() * 10)];
shipping[i] = {
orderNo: orderNo,
address: address,
recipienter: “Wilson”,
province: address.substr(0, 3),
city: address.substr(3, 3)
}
}
db.order.insert(orders);
db.shipping.insert(shipping);