这里,我整理了一些学到的复杂方法,并不全面,希望有用。
aggregate()
假如有以下数据:(引用 MongoDB 官网例子)
{ _id: 1, cust_id: "abc1", ord_date: ISODate("2012-11-02T17:04:11.102Z"), status: "A", amount: 50 }
{ _id: 2, cust_id: "xyz1", ord_date: ISODate("2013-10-01T17:04:11.102Z"), status: "A", amount: 100 }
{ _id: 3, cust_id: "xyz1", ord_date: ISODate("2013-10-12T17:04:11.102Z"), status: "D", amount: 25 }
{ _id: 4, cust_id: "xyz1", ord_date: ISODate("2013-10-11T17:04:11.102Z"), status: "D", amount: 125 }
{ _id: 5, cust_id: "abc1", ord_date: ISODate("2013-11-12T17:04:11.102Z"), status: "A", amount: 25 }
执行以下操作:
db.orders.aggregate([
{ $match: { status: "A" } },
{ $group: { _id: "$cust_id", total: { $sum: "$amount" } } },
{ $sort: { total: -1 } }
])
结果如下:
{ "_id" : "xyz1", "total" : 100 }
{ "_id" : "abc1", "total" : 75 }
解析: $match
是用来匹配查询条件,不可以在 find( ) 中使用;$sort
之前也讲过,这里为 -1 表示倒序排序;重点是 $group
,可以看到 _id: "$cust_id"
这段代码的意思 cust_id
字段重命名为 _id
,$sum
方法可以计算 amount
的总和。这里需要注意 cust_id
和 amount
前都加了 $
符号。
count()
db.user.count( { name : "MongoDB" } )
count()
的作用可见,就是计算查询出的结果的总数。
distinct()
distinct() 的作用是去除重复,但是得到的不是查询的全部结果,而是对应字段。
db.user.distinct( "name" )
group()
group()
和 $group
的作用其实是一致的,不过一个是方法一个是语法。
group( ) 有如下参数:
- key 分组依据
- initial 指定表
- $reduce : function( cur, prev ) { } 分组执行函数(第一个参数是当前文档对象,第二个参数是上一次function操作的累计对象)
db.user.group({
"key" : { "age" : true },
"initial" : { "user" : [] },
"$reduce" : function( cur, prev ) {
prev.user.push( cur.name );
}
})
/*或*/
db.user.group({
key : { "age" : true },
initial : { "user" : [] },
$reduce : function( cur, prev ) {
prev.user.push( cur.name );
}
})
group( ) 还提供了其他参数 :
- condition 过滤条件。
- finalize : function( out ) {} 这是个函数,每一组文档执行完后,都会触发此方法,那么在每组集合里面加上count也就是它的总和了。
db.user.group({
key : { "age" : true },
initial : { "user" : [] },
$reduce : function( cur, prev ) {
prev.user.push( cur.name );
},
finalize : function( out ) {
out.count = out.user.length;
},
condition : { "age" : { $gt : 10 } }
})
mapReduce( )
语法:
mapReduce( /*map*/function , /*reduce*/fucntion , { out : "out_collection_name" } )
db.user.mapReduce(
function(){ emit( key , value ) },
function( key , values ){},
{ out : "collection" }
)
示例:
var map = function() {
emit( this.name , { count : 1 } );
}
var reduce = function( key , values ) {
var result = { count : 0 };
for(var i = 0; i < values.length; i++ ) {
result.count += values[i].count;
}
return result;
}
db.user.mapReduce(
map ,
reduce ,
{ out : "collection" }
)
db.collection.find()
解析:
- map:这个称为映射函数,里面会调用 emit(key,value),集合会按照你指定的 key 进行映射分组。
- reduce:这个称为简化函数,会对map 分组后的数据进行分组简化,注意:在reduce(key,value) 中的 key 就是 emit 中的 key,vlaue 为 emit 分组后的 emit(value) 的集合,这里也就是很多 {“count”:1} 的数组。
- mapReduce : 这个就是最后执行的函数了,参数为map,reduce和一些可选参数。具体看图可知。
- finalize = function(key, return_value) {} 这个函数,每一组文档执行完后,都会触发此方法。在这个方法中可以对
return_value
进行处理。
这个方法执行之后会创建一个名为 collection 的集合。这个方法很复杂,一般不懂就不要用了。另外执行结果信息解释如下:
- result: “存放的集合名”
- input:传入文档的个数
- emit:此函数被调用的次数
- reduce:此函数被调用的次数
- output:最后返回文档的个数
runCommand( )
db.runCommand( command )
其中 command
可以是一个 document 或者 String。是要执行的命令。
示例:
/* 来自官网 */
db.runCommand(
{
group:
{
ns: 'orders',
key: { ord_dt: 1, 'item.sku': 1 },
cond: { ord_dt: { $gt: new Date( '01/01/2012' ) } },
$reduce: function ( curr, result ) { },
initial: { }
}
}
)
/* 前面的mapReduce */
db.runCommand({
mapreduce : "user",
map : map,
reduce : reduce,
out : "out_user"
})