The aggregation done by group is a bit complicated. First select the key on which the grouping is based, and then MongoDB will divide the collection into several groups based on the selected key value. A resulting document can then be produced by aggregating the documents within each group.
Like databases, groups are often used for statistics. MongoDB's group also has many limitations, such as: the returned result set cannot exceed 16M, the group operation will not handle more than 10,000 unique keys, and it seems that the index cannot be used [not very sure].
Group needs about a few parameters.
- key: The field used to group documents. and keyf both must have one
- keyf: can accept a javascript function. Fields used to dynamically determine the grouping documents. and key both must have one
- initial: initialization of variables used in reduce
- reduce: The reduce function to execute. Functions need to return a value.
- cond: The condition for performing filtering.
- finalize: The function that is finally executed on the result set before the reduce execution is completed and the result set is returned. optional.
Here's an example:
Insert test data first:
for
(var i=1; i<20; i++){
var num=i%6;
db.
test
.insert({_id:i,name:
"user_"
+i,age:num});
}
|
Common group query
db.
test
.group({
key:{age:
true
},
initial:{num:0},
$reduce:
function
(doc,prev){
prev.num++
}
});
db.runCommand({group:
{
ns:
"test"
,
key:{age:
true
},
initial:{num:0},
$reduce:
function
(doc,prev)
{
prev.num++
}
}
});
|
filter and then group
db.
test
.group({
key:{age:
true
},
initial:{num:0},
$reduce:
function
(doc,prev)
{
prev.num++
},
condition:{age:{$gt:2}}
});
db.runCommand({group:
{
ns:
"test"
,
key:{age:
true
},
initial:{num:0},
$reduce:
function
(doc,prev)
{
prev.num++},
condition:{age:{$gt:2}}
}
});
|
Ordinary $where query
db.
test
.
find
({$where:
function
(){
return
this.age>2;
}
});
|
group joint $where query
db.
test
.group({
key:{age:
true
},
initial:{num:0},
$reduce:
function
(doc,prev){
prev.num++
},
condition:{$where:
function
(){
return
this.age>2;
}
}
});
|
Use function return value grouping
//
注意,$keyf指定的函数一定要返回一个对象
db.
test
.group({
$keyf:
function
(doc){
return
{age:doc.age};},
initial:{num:0},
$reduce:
function
(doc,prev){
prev.num++
}
});
db.runCommand({group:
{
ns:
"test"
,
$keyf:
function
(doc){
return
{age:doc.age};},
initial:{num:0},
$reduce:
function
(doc,prev){
prev.num++}
}
});
|
use terminator
db.
test
.group({
$keyf:
function
(doc){
return
{age:doc.age};},
initial:{num:0},
$reduce:
function
(doc,prev){
prev.num++
},
finalize:
function
(doc){ doc.count=doc.num;delete doc.num; }
});
db.runCommand({group:
{
ns:
"test"
,
$keyf:
function
(doc){
return
{age:doc.age};},
initial:{num:0},
$reduce:
function
(doc,prev){
prev.num++},
finalize:
function
(doc){ doc.count=doc.num;delete doc.num; }
}
});
|
About MapReduce
//
首先插入测试数据
for
(var i=1;i<21;i++)
{
db.
test
.insert({_id:i,name:
'mm'
+i});
}
//
进行mapreduce
db.runCommand(
{
mapreduce:
'test'
,
map:
function
(){emit(this.name.substr(0,3),this);},
reduce:
function
(key,vals){
return
vals[0];},
//
注意:vals是一个Object对象而不是数组
out:
'wq'
});
|
Notice
1. mapreduce is grouped according to the first parameter of the emit function called in the map function.
2. Only when a key matches multiple documents after grouping according to the grouping key, the key and document set will be handed over to the reduce function for processing. E.g:
db.runCommand(
{
mapreduce:
'test'
,
map:
function
(){emit(this.name.substr(0,3),this);},
reduce:
function
(key,vals){
return
'wq'
;},
out:
'wq'
});
|
After executing the mapreduce command, view the wq table data:
db.wq.
find
()
{
"_id"
:
"mm1"
,
"value"
:
"wq"
}
{
"_id"
:
"mm2"
,
"value"
:
"wq"
}
{
"_id"
:
"mm3"
,
"value"
: {
"_id"
: 3,
"name"
:
"mm3"
} }
{
"_id"
:
"mm4"
,
"value"
: {
"_id"
: 4,
"name"
:
"mm4"
} }
{
"_id"
:
"mm5"
,
"value"
: {
"_id"
: 5,
"name"
:
"mm5"
} }
{
"_id"
:
"mm6"
,
"value"
: {
"_id"
: 6,
"name"
:
"mm6"
} }
{
"_id"
:
"mm7"
,
"value"
: {
"_id"
: 7,
"name"
:
"mm7"
} }
{
"_id"
:
"mm8"
,
"value"
: {
"_id"
: 8,
"name"
:
"mm8"
} }
{
"_id"
:
"mm9"
,
"value"
: {
"_id"
: 9,
"name"
:
"mm9"
} }
|
The above is the whole content of this article, I hope you like it.
Reprinted: http://www.jb51.net/article/65934.htm