NoSQL是K/V型数据库,本身不支持关系的,所以为了支持关系,就需要提供关联查询,这就是AGGREGATION产生的必然原因。
linux里的pipe:ps -ef|grep node|awk ‘{print $2}’|xargs kill -9
调用Model.aggregate()将会返回aggregate实例,他具有如下这些方法:
往aggregate管道里添加一个新的操作,比如新增加一个match匹配方式:
aggregate.append({ $project: { field: 1 }}, { $limit: 2 });
// or pass an array
var pipeline = [{ $match: { daw: 'Logic Audio X' }} ];
aggregate.append(pipeline);
只是一个语法糖的效果,方便统一的api
执行当前的aggregate管道内容,和之前的其他find操作一样,传入一个回调函数,执行这次计算操作,这里不多说。
在mongodb 2.6之后加入,告诉mongodb是否需要将本次汇总计算时暂时用硬盘存储。
批量设置游标大小
分组操作,表示对某些字段进行分组,比如我们对department字段进行分组:
aggregate.group({ _id: "$department" });
表示限制返回集合的大小,例如:
aggregate.limit(10);
表示汇总计算的筛选条件,比如:
aggregate.match({ department: { $in: [ "sales", "engineering" } } });
就是从以上条件中进行group分组汇总操作
查找附近的记录,如下代码:
aggregate.near({
  near: [40.724, -73.997],
  distanceField: "dist.calculated", // required
  maxDistance: 0.008,
  query: { type: "public" },
  includeLocs: "dist.location",
  uniqueDocs: true,
  num: 5
});
根据project表达式指定输入的字段或者计算的字段,语法如下:
{ $project: { <specifications> } }
比如有如下文档:
{
  "_id" : 1, 
  title: "abc123",
  isbn: "0001122223334",
  author: { last: "zzz", first: "aaa" },
  copies: 5
}
指定_id、title,author出现在输出的文档中:
{ 
    $project : { 
    title : 1 , 
    author : 1 
    }
 }
经过操作之后,就将输出
{ "_id" : 1, "title" : "abc123", "author" : { "last" : "zzz", "first" : "aaa" } }
当然,在之前也可以指定内嵌文档的字段,比如上面可以指定只输出author.last。 也可以通过加入计算操作,生成新的文档,数据库有如下文档:
{
  "_id" : 1,
  title: "abc123",
  isbn: "0001122223334",
  author: { last: "zzz", first: "aaa" },
  copies: 5
}
进行如下操作
db.books.aggregate(
   [
      {
         $project: {
            title: 1,
            isbn: {
               prefix: { $substr: [ "$isbn", 0, 3 ] },
               group: { $substr: [ "$isbn", 3, 2 ] },
               publisher: { $substr: [ "$isbn", 5, 4 ] },
               title: { $substr: [ "$isbn", 9, 3 ] },
               checkDigit: { $substr: [ "$isbn", 12, 1] }
            },
            lastName: "$author.last",
            copiesSold: "$copies"
         }
      }
   ]
)
操作之后的结果如下:
{
   "_id" : 1,
   "title" : "abc123",
   "isbn" : {
      "prefix" : "000",
      "group" : "11",
      "publisher" : "2222",
      "title" : "333",
      "checkDigit" : "4"
   },
   "lastName" : "zzz",
   "copiesSold" : 5
}
当查询汇总操作时的读取偏好,可以从以下这些中设置一个:
表示跳过多少条记录
aggregate.skip(10);
对计算结果排序
// 下面这些是等价的
aggregate.sort({ field: 'asc', test: -1 });
aggregate.sort('field -test');
将输入的文档数组解构,看个例子就明白了,有如下文档数据:
{ "_id" : 1, "item" : "ABC1", sizes: [ "S", "M", "L"] }
进行unwind操作:
db.inventory.aggregate( [ { $unwind : "$sizes" } ] )
输出结果:
{ "_id" : 1, "item" : "ABC1", "sizes" : "S" }
{ "_id" : 1, "item" : "ABC1", "sizes" : "M" }
{ "_id" : 1, "item" : "ABC1", "sizes" : "L" }
如下数据:
{ "_id" : 1, "A" : [ "red", "blue" ], "B" : [ "red", "blue" ] }
{ "_id" : 2, "A" : [ "red", "blue" ], "B" : [ "blue", "red", "blue" ] }
{ "_id" : 3, "A" : [ "red", "blue" ], "B" : [ "red", "blue", "green" ] }
{ "_id" : 4, "A" : [ "red", "blue" ], "B" : [ "green", "red" ] }
{ "_id" : 5, "A" : [ "red", "blue" ], "B" : [ ] }
{ "_id" : 6, "A" : [ "red", "blue" ], "B" : [ [ "red" ], [ "blue" ] ] }
{ "_id" : 7, "A" : [ "red", "blue" ], "B" : [ [ "red", "blue" ] ] }
{ "_id" : 8, "A" : [ ], "B" : [ ] }
{ "_id" : 9, "A" : [ ], "B" : [ "red" ] }
进行操作:
db.experiments.aggregate(
   [
     { $project: { A: 1, B: 1, sameElements: { $setEquals: [ "$A", "$B" ] }, _id: 0 } }
   ]
)
执行的结果如下:
{ "A" : [ "red", "blue" ], "B" : [ "red", "blue" ], "sameElements" : true }
{ "A" : [ "red", "blue" ], "B" : [ "blue", "red", "blue" ], "sameElements" : true }
{ "A" : [ "red", "blue" ], "B" : [ "red", "blue", "green" ], "sameElements" : false }
{ "A" : [ "red", "blue" ], "B" : [ "green", "red" ], "sameElements" : false }
{ "A" : [ "red", "blue" ], "B" : [ ], "sameElements" : false }
{ "A" : [ "red", "blue" ], "B" : [ [ "red" ], [ "blue" ] ], "sameElements" : false }
{ "A" : [ "red", "blue" ], "B" : [ [ "red", "blue" ] ], "sameElements" : false }
{ "A" : [ ], "B" : [ ], "sameElements" : true }
{ "A" : [ ], "B" : [ "red" ], "sameElements" : false }
字符串操作:
变量操作
$map 将每一条记录都经过map操作, { $map: { input: , as: , in: }
例如有数据:
{ _id: 1, quizzes: [ 5, 6, 7 ] }
{ _id: 2, quizzes: [ ] }
{ _id: 3, quizzes: [ 3, 8, 9 ] }
执行map操作:
db.grades.aggregate(
   [
      { $project:
         { adjustedGrades:
            {
              $map:
                 {
                   input: "$quizzes",
                   as: "grade",
                   in: { $add: [ "$$grade", 2 ] }
                 }
            }
         }
      }
   ]
)
输出结果,每个都加了2
{ "_id" : 1, "adjustedGrades" : [ 7, 8, 9 ] }
{ "_id" : 2, "adjustedGrades" : [ ] }
{ "_id" : 3, "adjustedGrades" : [ 5, 10, 11 ] }
$let 可以绑定变量,通过计算输出结果
文字操作:
日期操作:
条件表达式:
累加器:
日期统计
  Partaker.aggregate({
    $group:{
      _id:{year:{$year:"$time.join"},month:{$month:"$time.join"},day:{$dayOfMonth:"$time.join"}},
      count:{$sum:1}
    }
  },{
    $group:{
      _id:{year:"$_id.year",month:"$_id.month"},
      dailyusage:{$push:{day:"$_id.day",count:"$count"}}
    }
  },{
    $group:{
      _id:{year:"$_id.year"},
      monthlyusage:{$push:{month:"$_id.month",dailyusage:"$dailyusage"}}
    }
  },function(err,partakers){
    if(err) console.error(err);
    log.info({partakers:partakers},'结果');
  });
《SQL to Aggregation Mapping Chart》 http://docs.mongodb.org/manual/reference/sql-aggregation-comparison/