1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
// Tests a mapReduce for a relatively simple use case of computing an average. This is interesting
// because it does more than a simple sum for the reduce function and also needs to use a finalize
// function to do the final division to compute the average from the sum and totals.
//
// Cannot implicitly shard accessed collections because mapReduce cannot replace a sharded
// collection as output.
// @tags: [
// assumes_unsharded_collection,
// # mapReduce does not support afterClusterTime.
// does_not_support_causal_consistency,
// does_not_support_stepdowns,
// uses_map_reduce_with_temp_collections,
// ]
(function() {
"use strict";
const coll = db.mr_blog_posts;
coll.drop();
assert.commandWorked(coll.insert([
{
_id: "blog 1",
author: "x",
comments: [{user_id: "a", txt: "asdasdasd"}, {user_id: "b", txt: "asdasdasdasdasdasdas"}]
},
{
_id: "blog 2",
author: "y",
comments: [{user_id: "b", txt: "asdasdasdaaa"}, {user_id: "c", txt: "asdasdasdaasdasdas"}]
}
]));
function mapFn() {
for (let comment of this.comments) {
emit(comment.user_id, {totalSize: comment.txt.length, num: 1});
}
}
function reduceFn(user_id, values) {
let reduced = {totalSize: 0, num: 0};
for (let value of values) {
reduced.totalSize += value.totalSize;
reduced.num += value.num;
}
return reduced;
}
const outputColl = db.mr_compute_avg_out;
outputColl.drop();
function reformat(cmdResult) {
let x = {};
let cursor;
if (cmdResult.results)
cursor = cmdResult.results;
else
cursor = outputColl.find();
cursor.forEach(result => {
x[result._id] = result.value;
});
return x;
}
function finalizeFn(user_id, res) {
res.avg = res.totalSize / res.num;
return res;
}
let res = coll.mapReduce(mapFn, reduceFn, {finalize: finalizeFn, out: outputColl.getName()});
assert.commandWorked(res);
let resultAsSingleObj = reformat(res);
assert.eq(9, resultAsSingleObj.a.avg, () => tojson(resultAsSingleObj));
assert.eq(16, resultAsSingleObj.b.avg, () => tojson(resultAsSingleObj));
assert.eq(18, resultAsSingleObj.c.avg, () => tojson(resultAsSingleObj));
outputColl.drop();
res = coll.mapReduce(mapFn, reduceFn, {finalize: finalizeFn, out: {inline: 1}});
assert.commandWorked(res);
resultAsSingleObj = reformat(res);
assert.eq(9, resultAsSingleObj.a.avg, () => tojson(resultAsSingleObj));
assert.eq(16, resultAsSingleObj.b.avg, () => tojson(resultAsSingleObj));
assert.eq(18, resultAsSingleObj.c.avg, () => tojson(resultAsSingleObj));
outputColl.drop();
assert(!("result" in res), () => `Expected inline output with 'results': ${tojson(res)}`);
res = coll.mapReduce(mapFn, reduceFn, {finalize: finalizeFn, out: {inline: 1}});
assert.commandWorked(res);
resultAsSingleObj = reformat(res);
assert.eq(9, resultAsSingleObj.a.avg, () => tojson(resultAsSingleObj));
assert.eq(16, resultAsSingleObj.b.avg, () => tojson(resultAsSingleObj));
assert.eq(18, resultAsSingleObj.c.avg, () => tojson(resultAsSingleObj));
assert(!("result" in res), () => `Expected inline output with 'results': ${tojson(res)}`);
}());
|