聚合操作,游标的使用及排序分页操作
- 聚合操作:
- count:查看符合某些条件的集合中记录的个数;
- 查看集合user的记录数:db.user.count();
- 查看集合user中年龄大于20的记录的个数:db.user.count({“age”:{$gt:20}});
- 查看集合user的记录数:db.user.count();
- distinct:查看集合中某个属性的独立存在的个数;
- 获得不同年龄的数组:db.user.distinct(“age”);
- 获得不同年龄值的个数:db.user.distinct(“age”).length;
- 获得不同年龄的数组:db.user.distinct(“age”);
- group:对集合按照某一属性分组,形成一个K-V模型;
- 语法:db.mycoll.group( { key : …, initial: …, reduce : … [, finalize: …] [, condition: …] } );
- key:分组的键;
- initial:每个分组使用的初始化函数;
- reduce:此函数的第一个参数是当前的文档对象,第二个参数是上次函数(即initial函数)操作的累计对象,有多少个文档,$reduce就会调用多少次;
- finalize:每一组文档执行完之后,会触发执行的一个函数,参数是上次函数(即initial函数)操作的累计对象;
- condtion:过滤条件;
- 按照年龄分组的例子:db.user.group({key:{age:true}, initial:{user:[]}, reduce:function(cur, prev){prev.user.push(cur.name);}}),push函数是把一个值加入到数组中;
- 按照年龄分组,过滤掉年龄大于25的记录,并且添加一个用户数量的属性count:db.user.group({key:{age:true}, initial:{user:[]}, reduce:function(cur, prev){prev.user.push(cur.name);}, finalize:function(prev){prev.count=prev.user.length;}, condition:{age:{$lte:25}}});
- 语法:db.mycoll.group( { key : …, initial: …, reduce : … [, finalize: …] [, condition: …] } );
- mapReduce:其实是一种编程模型,用在分布式计算中.可以把问题划分为多个不同的部分并分发到不同的服务器并行处理,每台服务器都把分配给自己的一部分处理完成后把结果集返回给主服务器,主服务器汇总结果后完成问题的处理;
- 语法:db.mycoll.mapReduce( mapFunction , reduceFunction , <optional params> );
- mapFunction:映射函数,里面会调用emit(key, value),集合会按照指定的key进行映射分组;
- reduceFunction:;简化函数,会对map分组后的数据进行分组简化.其中reduce(key, value)中的key就是emit中的key,value为emit分组后的emit(value)的集合,它有一个或者多个对应于键的文档组成;
- 可选参数;
- 原理:map首先将文档映射到集合并操作文档,这一步可能产生多个键和多个值或者什么也没有(文档中要处理的值为空).而后按照键分组,并将产生的值组成列表放到对应的键中,reduce则把列表中的值化简为一个值,这个值被返回,而后继续按键分组,进行化简,直到每个键在列表中只有一个值为止,这个值也就是最终结果;
- 例子;
- 语法:db.mycoll.mapReduce( mapFunction , reduceFunction , <optional params> );
- count:查看符合某些条件的集合中记录的个数;
- 游标的使用:
- 使用while循环遍历输出:var cursor=db.user.find(); while(cursor.hasNext()) { printjson(cursor.next()); };(其中hasNext()函数判断是否有记录,next()函数返回下一条记录)
- pringjson()函数是内置函数,能够将结果输出为json格式;
- 得到数据集集合,遍历完之后游标便销毁;
- 使用forEach()函数遍历:db.user.find().forEach(printjson);
- 像访问数组一样使用游标:var cursor=db.user.find();printjson(cursor[0]);(会把访问的数据都加载ram中,如果数据量很大的话非常消耗内存)
- 直接转换成数组访问:var array=db.user.find().toArray();array[0];
- 使用while循环遍历输出:var cursor=db.user.find(); while(cursor.hasNext()) { printjson(cursor.next()); };(其中hasNext()函数判断是否有记录,next()函数返回下一条记录)
- 排序操作:
- 语法:db.mycoll.find().sort({col:value, …});
- col:表示按照排序的列;
- value:可以取1和-1,1表示升序,-1表示降序;
- 查找所有记录,并按照年龄升序,名称降序显示:db.user.find().sort({“age”:1, “name”:-1}),select name, age from user order by age desc, name asc;
- 还可以通过其它方法实现,db.mycoll.find([query], [fields])操作是根据query过滤记录,先后显示fields里面指定的列,如果query给默认的话({}就是默认的参数),只需要指定列名及排序方式即可:select name, age from user order by age desc, name asc;
- 先按年龄升序,然后按照名称升序排序:select name from user order by age asc, name asc;
- 语法:db.mycoll.find().sort({col:value, …});
- 分页操作:
- 使用db.mycoll.find().skip(n)操作和db.mycoll.find().limit(n)实现,前者是跳过之前多少条记录,后者是显示多少条记录:skip((pageIndex-1) * pageSize).limit(pageSize);
- 排序后的结果,每页两条记录,显示第二页:db.user.find().sort({“age”:1, “name”:-1}).skip(2).limit(2);
— 测试数据;
db.user.drop()
db.user.insert({“name”:”jack”, “age”:20})
db.user.insert({“name”:”joe”, “age”:22})
db.user.insert({“name”:”mary”, “age”:26})
db.user.insert({“name”:”kobe”, “age”:20})
db.user.insert({“name”:”wade”, “age”:22})
db.user.insert({“name”:”yi”, “age”:22})
db.user.find()
.png)
— mapReduce操作;
1.创建map函数;
function map(){ emit(this.age, {count:1}); }
.png)
2.创建reduce函数;
function reduce(key, value){
var result = {count:0};
for (var i = 0; i < value.length; i++){
result.count += value[i].count;
}
return result;
}
.png)
3.执行mapReduce操作,并把结果集存放在集合collection中;
db.user.mapReduce(map, reduce, {out:”collection”})
.png)
result:存放集合名;
timeMillis:执行的时间,单位是毫秒;
input:传入文档的个数;
emit:emit函数被调用的次数;
reduce:reduce函数被调用的次数;
output:最后返回文档的个数;
4.查看collection中的结果;
db.collection.find()
.png)