五、MongoDB 聚合

1、count
————————————————————————
> db.ysq.count() // 执行速度很快
> db.ysq.count({"x" : 1}) // 增加查询条件会使count变慢
————————————————————————
 
2、distinct
————————————————————————
> db.runCommand( { "distinct" : "people", "key" : "age" } )
————————————————————————
 
3、group
与关系型数据库的 GROUP BY 差不多。
例子:在最近30天的股价集合中获取每天收市价
————————————————————————
-- 股价文档:
{ "day" : "2013/06/07" , "time" : "2013/06/07 23:22:53 GMT-400" ,"price" : "4.23" }

-- group
> db.runCommand( { "group" : 
    "ns" : "ysq" ,    -- 指定要进行分组的集合
    "key" : "day" ,   -- 指定文档分组依据的键
    "inital" : { "time" : 0 } ,-- 每一组reduce函数调用的初始时间
    "$ruduce" : function(doc, prev) { -- 每个文档都对应一次调用,doc为当前文档,prev为本组当前结果
        if (doc.time > prev.time) {
            prev.price = doc.price ;   
            prev.time = doc.time ;
        }
    } ,
    "condition" : { "day" : { "$gt" : "2013/05/07" } } -- 过滤条件,condition也可简写为cond或q
} )

-- 结果
{
    "retval" : -- 返回的文档数组
        [
            { 
                "day" : "2013/06/07" , -- 默认加进来的
                "time" : "2013/06/07 23:22:53 GMT-400" , -- 初始化设置,然后主动更新
                "price" : "4.23"  -- price是显式设置的
            } ,
            ... ...
        ],
    "count" : 734, --使用的文档总是
    "keys" : 30,-- key有多少个不同的值
    "ok" : 1
}
————————————————————————
注:有的文档没有包含依据的键,会被分到一组,以"day" : null 形式存在。在"condition"中加入"day" : {"$exits" : true}可过滤该组
 
3.1、使用完成器
例子:每篇博客文章有多个标签tag。现要找出每天最热点的标签。
————————————————————————
-- 先按天分组,为每个标签计数:
db.posts.group({
    "key" : {"tags" : true},
    "initial" : {"tags" : {}},
    "$reduce" : function(doc, prev) {
        for(i in doc.tags) {
            if(doc.tags[i] in prev.tags) {
                prev.tags[doc.tags[i]] ++ ;
            } else {
                prev.tags[dov.tags[i]] = 1;
            }
        }
    }
})

-- 结果:
[
    {"day" : "2012/01/12","tags" : {"nosql" : 4,"winter" : 10,"sledding" : 2} },
    {"day" : "2012/01/13","tags" : {"soda" : 5,"php" : 2} },
    {"day" : "2012/01/14","tags" : {"python" : 6,"winter" : 4,"nosql" : 15} }
]

-- 使用完成器精减结果
"finalize" : function(prev) {
    var mostPopular = 0 ;
    for ( i in prev.tags ) {
        if( prev.tags[i] > mostPopular ) {
            prev.tag = i;
            mostPopular  = prev.tags[i];
        }
    }
    delete prev.tags;
}

-- 结果:
[
    {"day" : "2012/01/12","tags" : "winter"},
    {"day" : "2012/01/13","tags" : "soda" },
    {"day" : "2012/01/14","tags" : "nosql"} }
]
————————————————————————
 
3.2 将函数作为键使用
例子:由于每个作者习惯不一样,刚才的tag,可能有些作者写的是"nosql",有些写的是"noSql",这时可以使用函数作为键
定义分组函数就要用到$keyf(不再是key)
————————————————————————
"$keyf" : function(x) {return x.category.toLowerCase();}
————————————————————————
 
 
4、MapReduce
(略)
 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值