设为首页 收藏本站
查看: 892|回复: 0

[经验分享] MongoDB : Aggregation mongo聚合操作详细说明

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2015-11-10 14:41:48 | 显示全部楼层 |阅读模式
This page last changed on Feb 02, 2012 by
dwight
.

  • Aggregation Framework
  • Count
  • Distinct
  • Group

    • Examples
    • Using Group from Various Languages


  • Map/Reduce
  • See Also
  Mongo includes utility functions which provide server-side count, distinct, and
group by operations.  More advanced aggregate functions can be crafted using
MapReduce.

Aggregation Framework
  v2.2+
  This is a new module in the v2.2 release.  You can test it via v2.1.0 in the 2.1 development (unstable) branch.
Aggregation Framework

Count
  count() returns the number of objects in a collection or matching a query. If a document selector is provided, only the number of matching documents will be returned.
  size() is like count() but takes into consideration any limit() or skip() specified for the query.

db.collection.count(selector);

  For example:

print( "# of objects: " + db.mycollection.count() );
print( db.mycollection.count( {active:true} );

  count is faster if an index exists for the condition in the selector. For example, to make the count on
active fast, invoke

db.mycollection.ensureIndex( {active:1} );
Distinct
  The distinct command returns returns a list of distinct values for the given
key across a collection.
  Command is of the form:

{ distinct : <collection_name>, key : <key>[, query : <query>] }
  although many drivers have a helper function for distinct.

> db.addresses.insert({&quot;zip-code&quot;: 10010})
> db.addresses.insert({&quot;zip-code&quot;: 10010})
> db.addresses.insert({&quot;zip-code&quot;: 99701})
> // shell helper:
> db.addresses.distinct(&quot;zip-code&quot;);
[ 10010, 99701 ]
> // running as a command manually:
> db.runCommand( { distinct: 'addresses', key: 'zip-code' } )
{ &quot;values&quot; : [ 10010, 99701 ], &quot;ok&quot; : 1 }

  distinct may also reference a nested key:

> db.comments.save({&quot;user&quot;: {&quot;points&quot;: 25}})
> db.comments.save({&quot;user&quot;: {&quot;points&quot;: 31}})
> db.comments.save({&quot;user&quot;: {&quot;points&quot;: 25}})
> db.comments.distinct(&quot;user.points&quot;);
[ 25, 31 ]

  You can add an optional query parameter to distinct as well

> db.address.distinct( &quot;zip-code&quot; , { age : 30 } )
  Note: the distinct command results are returned as a single BSON object.  If the results could be large (> max document size – 4/16MB ), use map/reduce instead.


DSC0000.gif
Covered Index Use

Starting with 1.7.3 distinct can use an index not only to find the documents in the query, but also to return the data.

Group
  Note: currently one must use map/reduce instead of group() in sharded MongoDB configurations.
  group returns an array of grouped items. The command is similar to SQL's group by. The SQL statement

select a,b,sum(c) csum from coll where active=1 group by a,b

  corresponds to the following in MongoDB:

db.coll.group(
{key: { a:true, b:true },
cond: { active:1 },
reduce: function(obj,prev) { prev.csum &#43;= obj.c; },
initial: { csum: 0 }
});

  Note: the result is returned as a single BSON object and for this reason must be fairly small – less than 10,000 keys, else you will get an exception. For larger grouping operations without limits, please use
map/reduce .
  group takes a single object parameter containing the following fields:


  • key: Fields to group by.
  • reduce: The reduce function aggregates (reduces) the objects iterated. Typical operations of a reduce function include summing and counting.
    reduce takes two arguments: the current document being iterated over and the aggregation counter object. In the example above, these arguments are named
    obj and prev.
  • initial: initial value of the aggregation counter object.
  • keyf: An optional function returning a &quot;key object&quot; to be used as the grouping key. Use this instead of
    key to specify a key that is not a single/multiple existing fields. Could be used to group by day of the week, for example. Set in lieu of
    key.
  • cond: An optional condition that must be true for a row to be considered. This is essentially a
    find() query expression object. If null, the reduce function will run against all rows in the collection.
  • finalize: An optional function to be run on each item in the result set just before the item is returned. Can either modify the item (e.g., add an average field given a count and a total) or return a replacement object (returning a new
    object with just _id and average fields). See jstests/group3.js for examples.
  To order the grouped data, simply sort it client-side upon return. The following example is an implementation of
count() using group().

function gcount(collection, condition) {
var res =
db[collection].group(
{ key: {},
initial: {count: 0},
reduce: function(obj,prev){ prev.count&#43;&#43;;},
cond: condition } );
// group() returns an array of grouped items.  here, there will be a single
  // item, as key is {}.
  return res[0] ? res[0].count : 0;
}

Examples
  The examples assume data like this:

{ domain: &quot;www.mongodb.org&quot;
, invoked_at: {d:&quot;2009-11-03&quot;, t:&quot;17:14:05&quot;}
, response_time: 0.05
, http_action: &quot;GET /display/DOCS/Aggregation&quot;
}

  Show me stats for each http_action in November 2009:

db.test.group(
{ cond: {&quot;invoked_at.d&quot;: {$gte: &quot;2009-11&quot;, $lt: &quot;2009-12&quot;}}
, key: {http_action: true}
, initial: {count: 0, total_time:0}
, reduce: function(doc, out){ out.count&#43;&#43;; out.total_time&#43;=doc.response_time }
, finalize: function(out){ out.avg_time = out.total_time / out.count }
} );
[
{
&quot;http_action&quot; : &quot;GET /display/DOCS/Aggregation&quot;,
&quot;count&quot; : 1,
&quot;total_time&quot; : 0.05,
&quot;avg_time&quot; : 0.05
}
]

  Show me stats for each domain for each day in November 2009:

db.test.group(
{ cond: {&quot;invoked_at.d&quot;: {$gte: &quot;2009-11&quot;, $lt: &quot;2009-12&quot;}}
, key: {domain: true, invoked_at.d: true}
, initial: {count: 0, total_time:0}
, reduce: function(doc, out){ out.count&#43;&#43;; out.total_time&#43;=doc.response_time }
, finalize: function(out){ out.avg_time = out.total_time / out.count }
} );
[
{
&quot;http_action&quot; : &quot;GET /display/DOCS/Aggregation&quot;,
&quot;count&quot; : 1,
&quot;total_time&quot; : 0.05,
&quot;avg_time&quot; : 0.05
}
]

Using Group from Various Languages
  Some language drivers provide a group helper function.  For those that don't, one can manually issue the db command for group.  Here's an example using the Mongo shell syntax:

> db.foo.find()
{&quot;_id&quot; :  ObjectId( &quot;4a92af2db3d09cb83d985f6f&quot;)  , &quot;x&quot; : 1}
{&quot;_id&quot; :  ObjectId( &quot;4a92af2fb3d09cb83d985f70&quot;)  , &quot;x&quot; : 3}
{&quot;_id&quot; :  ObjectId( &quot;4a92afdab3d09cb83d985f71&quot;)  , &quot;x&quot; : 3}
> db.$cmd.findOne({group : {
... ns : &quot;foo&quot;,
... cond : {},
... key : {x : 1},
... initial : {count : 0},
... $reduce : function(obj,prev){prev.count&#43;&#43;;}}})
{&quot;retval&quot; : [{&quot;x&quot; : 1 , &quot;count&quot; : 1},{&quot;x&quot; : 3 , &quot;count&quot; : 2}] , &quot;count&quot; : 3 , &quot;keys&quot; : 2 , &quot;ok&quot; : 1}

  If you use the database command with keyf (instead of key) it must be prefixed with a $. For example:

db.$cmd.findOne({group : {
... ns : &quot;foo&quot;,
... $keyf : function(doc) { return {&quot;x&quot; : doc.x}; },
... initial : {count : 0},
... $reduce : function(obj,prev) { prev.count&#43;&#43;; }}})

Map/Reduce
  MongoDB provides a
MapReduce facility for more advanced aggregation needs. CouchDB users: please note that basic queries in MongoDB do not use map/reduce.

See Also


  • jstests/eval2.js for an example of group() usage
  • Advanced Queries
  site:
http://api.mongodb.org/wiki/current/Aggregation.html#Aggregation-Group

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-137624-1-1.html 上篇帖子: MongoDB入门学习笔记之mongo shell和java客户端 下篇帖子: MongoDB学习笔记4--mongo的数据修改
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表