当前位置: 首页 > 数据库 > MongoDB > 正文

MongoDB聚合

2018-04-23 来源:博客园/refactor

MongoDB除了基本的查询功能,还提供了很多强大的聚合工具,其中简单的可计算集合中的文档个数,

复杂的可利用MapReduce做复杂数据分析.

1.count

count返回集合中的文档数量

db.refactor.count()

不管集合有多大,都能很快的返回文档数量.

可以传递查询,MongoDB会计算查询结果的数量

db.refactor.count({"username":"refactor"})

但是增加查询条件会使count变慢.

2.distinct

distinct用来找出给定键的所有不同值.使用时必须指定集合和键.

如:

db.runCommand({"distinct":"refactor","key":"username"})

3.group

group先选定分组所依据的键,MongoDB将会将集合依据选定键值的不同分成若干组.然后可以通过聚合每一组内的文档,

产生一个结果文档.

如:

db.runCommand(

{

  "group":

  {

    "ns":"refactor",

    "key":{"username":true},

    "initial":{"count":0},

    "$reduce":function(doc,prev)

    {

      prev.count++;

    },

    "condition":{"age":{"$gt":40}}

  }

}

)

 "ns":"refactor",

指定要进行分组的集合

   "key":{"username":true},

指定文档分组的依据,这里是username键,所有username键的值相等的被划分到一组,true为返回键username的值

   "initial":{"count":0},

每一组reduce函数调用的初始个数.每一组的所有成员都会使用这个累加器.

   "$reduce":function(doc,prev){...}

每个文档都对应的调用一次.系统会传递两个参数:当前文档和累加器文档.

"condition":{"age":{"$gt":40}}

这个age的值大于40的条件

4.使用完成器

完成器用于精简从数据库传到用户的数据.group命令的输出一定要能放在单个数据库相应中.

"finalize"附带一个函数,在数组结果传递到客户端之前被调用一次.

db.runCommand(

  {

    "group":

    {

      "ns":"refactor",

      "key":{"username":true},

      "initial":{"count":0},

      "$reduce":function(doc,prev)

      {

        prev.count++;

      },

      "finalize":function(doc)

      {

        doc.num=doc.count;

        delete doc.count;

      }

    }

  }

)

finalize能修改传递的参数也能返回新值.

5.将数组作为键使用

有些时候分组所依据的条件很复杂,不仅是一个键.比如要使用group计算每个类别有多篇博客文章.由于有很多作者,

给文章分类时可能不规律的使用了大小写.所以,如果要是按类别名来分组,最后"MongoDB"和"mongodb"就是不同的组.

为了消除这种大小写的影响,就要定义一个函数来确定文档所依据的键.

定义分组要用到$keyf

db.runCommand(

{

 "group":

  {

   "ns":"refactor",

   "$keyf":function(doc){return {"username":doc.username.toLowerCase()}},

   "initial":{"count":0},

   "$reduce":function(doc,prev)

      {

       prev.count++;

      }

  }

}

)