Files
mongo/jstests/aggregation/testall.js
Mathias Stearn a2cf5a59b7 SERVER-11711 Make aggregation/testall.js not depend on document order
Needed to make tests pass with agg on top of new query framework. The order of fields returned by
the new query framework is undefined due to SERVER-11833.
2013-11-26 13:14:59 -05:00

1549 lines
30 KiB
JavaScript

/*
Run all the aggregation tests
*/
/* load the test documents */
load('jstests/aggregation/data/articles.js');
// make sure we're using the right db; this is the same as "use mydb;" in shell
db = db.getSiblingDB("aggdb");
// just passing through fields
var p1 = db.runCommand(
{ aggregate : "article", pipeline : [
{ $project : {
tags : 1,
pageViews : 1
}}
]});
var p1result = [
{
"_id" : 1,
"pageViews" : 5,
"tags" : [
"fun",
"good",
"fun"
]
},
{
"_id" : 2,
"pageViews" : 7,
"tags" : [
"fun",
"nasty"
]
},
{
"_id" : 3,
"pageViews" : 6,
"tags" : [
"nasty",
"filthy"
]
}
];
assert.docEq(p1.result, p1result, 'p1 failed');
// a simple array unwinding
var u1 = db.runCommand(
{ aggregate : "article", pipeline : [
{ $unwind : "$tags" }
]});
var u1result = [
{
"_id" : 1,
"title" : "this is my title",
"author" : "bob",
"posted" : ISODate("2004-03-21T18:59:54Z"),
"pageViews" : 5,
"tags" : "fun",
"comments" : [
{
"author" : "joe",
"text" : "this is cool"
},
{
"author" : "sam",
"text" : "this is bad"
}
],
"other" : {
"foo" : 5
}
},
{
"_id" : 1,
"title" : "this is my title",
"author" : "bob",
"posted" : ISODate("2004-03-21T18:59:54Z"),
"pageViews" : 5,
"tags" : "good",
"comments" : [
{
"author" : "joe",
"text" : "this is cool"
},
{
"author" : "sam",
"text" : "this is bad"
}
],
"other" : {
"foo" : 5
}
},
{
"_id" : 1,
"title" : "this is my title",
"author" : "bob",
"posted" : ISODate("2004-03-21T18:59:54Z"),
"pageViews" : 5,
"tags" : "fun",
"comments" : [
{
"author" : "joe",
"text" : "this is cool"
},
{
"author" : "sam",
"text" : "this is bad"
}
],
"other" : {
"foo" : 5
}
},
{
"_id" : 2,
"title" : "this is your title",
"author" : "dave",
"posted" : ISODate("2030-08-08T04:11:10Z"),
"pageViews" : 7,
"tags" : "fun",
"comments" : [
{
"author" : "barbara",
"text" : "this is interesting"
},
{
"author" : "jenny",
"text" : "i like to play pinball",
"votes" : 10
}
],
"other" : {
"bar" : 14
}
},
{
"_id" : 2,
"title" : "this is your title",
"author" : "dave",
"posted" : ISODate("2030-08-08T04:11:10Z"),
"pageViews" : 7,
"tags" : "nasty",
"comments" : [
{
"author" : "barbara",
"text" : "this is interesting"
},
{
"author" : "jenny",
"text" : "i like to play pinball",
"votes" : 10
}
],
"other" : {
"bar" : 14
}
},
{
"_id" : 3,
"title" : "this is some other title",
"author" : "jane",
"posted" : ISODate("2000-12-31T05:17:14Z"),
"pageViews" : 6,
"tags" : "nasty",
"comments" : [
{
"author" : "will",
"text" : "i don't like the color"
},
{
"author" : "jenny",
"text" : "can i get that in green?"
}
],
"other" : {
"bar" : 14
}
},
{
"_id" : 3,
"title" : "this is some other title",
"author" : "jane",
"posted" : ISODate("2000-12-31T05:17:14Z"),
"pageViews" : 6,
"tags" : "filthy",
"comments" : [
{
"author" : "will",
"text" : "i don't like the color"
},
{
"author" : "jenny",
"text" : "can i get that in green?"
}
],
"other" : {
"bar" : 14
}
}
];
assert.docEq(u1.result, u1result, 'u1 failed');
// unwind an array at the end of a dotted path
db.ut.drop();
db.ut.save({_id: 4, a:1, b:{e:7, f:[4, 3, 2, 1]}, c:12, d:17});
var u2 = db.runCommand(
{ aggregate : "ut", pipeline : [
{ $unwind : "$b.f" }
]});
var u2result = [
{
"_id" : 4,
"a" : 1,
"b" : {
"e" : 7,
"f" : 4
},
"c" : 12,
"d" : 17
},
{
"_id" : 4,
"a" : 1,
"b" : {
"e" : 7,
"f" : 3
},
"c" : 12,
"d" : 17
},
{
"_id" : 4,
"a" : 1,
"b" : {
"e" : 7,
"f" : 2
},
"c" : 12,
"d" : 17
},
{
"_id" : 4,
"a" : 1,
"b" : {
"e" : 7,
"f" : 1
},
"c" : 12,
"d" : 17
}
];
assert.docEq(u2.result, u2result, 'u2 failed');
// combining a projection with unwinding an array
var p2 = db.runCommand(
{ aggregate : "article", pipeline : [
{ $project : {
author : 1,
tags : 1,
pageViews : 1
}},
{ $unwind : "$tags" }
]});
var p2result = [
{
"_id" : 1,
"author" : "bob",
"pageViews" : 5,
"tags" : "fun"
},
{
"_id" : 1,
"author" : "bob",
"pageViews" : 5,
"tags" : "good"
},
{
"_id" : 1,
"author" : "bob",
"pageViews" : 5,
"tags" : "fun"
},
{
"_id" : 2,
"author" : "dave",
"pageViews" : 7,
"tags" : "fun"
},
{
"_id" : 2,
"author" : "dave",
"pageViews" : 7,
"tags" : "nasty"
},
{
"_id" : 3,
"author" : "jane",
"pageViews" : 6,
"tags" : "nasty"
},
{
"_id" : 3,
"author" : "jane",
"pageViews" : 6,
"tags" : "filthy"
}
];
assert.docEq(p2.result, p2result, 'p2 failed');
// pulling values out of subdocuments
var p3 = db.runCommand(
{ aggregate : "article", pipeline : [
{ $project : {
otherfoo : "$other.foo",
otherbar : "$other.bar"
}}
]});
var p3result = [
{
"_id" : 1,
"otherfoo" : 5
},
{
"_id" : 2,
"otherbar" : 14
},
{
"_id" : 3,
"otherbar" : 14
}
];
assert.docEq(p3.result, p3result, 'p3 failed');
// projection includes a computed value
var p4 = db.runCommand(
{ aggregate : "article", pipeline : [
{ $project : {
author : 1,
daveWroteIt : { $eq:["$author", "dave"] }
}}
]});
var p4result = [
{
"_id" : 1,
"author" : "bob",
"daveWroteIt" : false
},
{
"_id" : 2,
"author" : "dave",
"daveWroteIt" : true
},
{
"_id" : 3,
"author" : "jane",
"daveWroteIt" : false
}
];
assert.docEq(p4.result, p4result, 'p4 failed');
// projection includes a virtual (fabricated) document
var p5 = db.runCommand(
{ aggregate : "article", pipeline : [
{ $project : {
author : 1,
pageViews : 1,
tags : 1
}},
{ $unwind : "$tags" },
{ $project : {
author : 1,
subDocument : { foo : "$pageViews", bar : "$tags" }
}}
]});
var p5result = [
{
"_id" : 1,
"author" : "bob",
"subDocument" : {
"foo" : 5,
"bar" : "fun"
}
},
{
"_id" : 1,
"author" : "bob",
"subDocument" : {
"foo" : 5,
"bar" : "good"
}
},
{
"_id" : 1,
"author" : "bob",
"subDocument" : {
"foo" : 5,
"bar" : "fun"
}
},
{
"_id" : 2,
"author" : "dave",
"subDocument" : {
"foo" : 7,
"bar" : "fun"
}
},
{
"_id" : 2,
"author" : "dave",
"subDocument" : {
"foo" : 7,
"bar" : "nasty"
}
},
{
"_id" : 3,
"author" : "jane",
"subDocument" : {
"foo" : 6,
"bar" : "nasty"
}
},
{
"_id" : 3,
"author" : "jane",
"subDocument" : {
"foo" : 6,
"bar" : "filthy"
}
}
];
assert.docEq(p5.result, p5result, 'p5 failed');
// multi-step aggregate
// nested expressions in computed fields
var p6 = db.runCommand(
{ aggregate : "article", pipeline : [
{ $project : {
author : 1,
tags : 1,
pageViews : 1
}},
{ $unwind : "$tags" },
{ $project : {
author : 1,
tag : "$tags",
pageViews : 1,
daveWroteIt : { $eq:["$author", "dave"] },
weLikeIt : { $or:[ { $eq:["$author", "dave"] },
{ $eq:["$tags", "good"] } ] }
}}
]});
var p6result = [
{
"_id" : 1,
"author" : "bob",
"pageViews" : 5,
"tag" : "fun",
"daveWroteIt" : false,
"weLikeIt" : false
},
{
"_id" : 1,
"author" : "bob",
"pageViews" : 5,
"tag" : "good",
"daveWroteIt" : false,
"weLikeIt" : true
},
{
"_id" : 1,
"author" : "bob",
"pageViews" : 5,
"tag" : "fun",
"daveWroteIt" : false,
"weLikeIt" : false
},
{
"_id" : 2,
"author" : "dave",
"pageViews" : 7,
"tag" : "fun",
"daveWroteIt" : true,
"weLikeIt" : true
},
{
"_id" : 2,
"author" : "dave",
"pageViews" : 7,
"tag" : "nasty",
"daveWroteIt" : true,
"weLikeIt" : true
},
{
"_id" : 3,
"author" : "jane",
"pageViews" : 6,
"tag" : "nasty",
"daveWroteIt" : false,
"weLikeIt" : false
},
{
"_id" : 3,
"author" : "jane",
"pageViews" : 6,
"tag" : "filthy",
"daveWroteIt" : false,
"weLikeIt" : false
}
];
assert.docEq(p6.result, p6result, 'p6 failed');
// slightly more complex computed expression; $ifNull
var p7 = db.runCommand(
{ aggregate : "article", pipeline : [
{ $project : {
theSum : { $add:["$pageViews",
{ $ifNull:["$other.foo",
"$other.bar"] } ] }
}}
]});
var p7result = [
{
"_id" : 1,
"theSum" : 10
},
{
"_id" : 2,
"theSum" : 21
},
{
"_id" : 3,
"theSum" : 20
}
];
assert.docEq(p7.result, p7result, 'p7 failed');
// dotted path inclusion; _id exclusion
var p8 = db.runCommand(
{ aggregate : "article", pipeline : [
{ $project : {
_id : 0,
author : 1,
tags : 1,
"comments.author" : 1
}},
{ $unwind : "$tags" }
]});
var p8result = [
{
"author" : "bob",
"tags" : "fun",
"comments" : [
{
"author" : "joe"
},
{
"author" : "sam"
}
]
},
{
"author" : "bob",
"tags" : "good",
"comments" : [
{
"author" : "joe"
},
{
"author" : "sam"
}
]
},
{
"author" : "bob",
"tags" : "fun",
"comments" : [
{
"author" : "joe"
},
{
"author" : "sam"
}
]
},
{
"author" : "dave",
"tags" : "fun",
"comments" : [
{
"author" : "barbara"
},
{
"author" : "jenny"
}
]
},
{
"author" : "dave",
"tags" : "nasty",
"comments" : [
{
"author" : "barbara"
},
{
"author" : "jenny"
}
]
},
{
"author" : "jane",
"tags" : "nasty",
"comments" : [
{
"author" : "will"
},
{
"author" : "jenny"
}
]
},
{
"author" : "jane",
"tags" : "filthy",
"comments" : [
{
"author" : "will"
},
{
"author" : "jenny"
}
]
}
];
assert.docEq(p8.result, p8result, 'p8 failed');
// collapse a dotted path with an intervening array
var p9 = db.runCommand(
{ aggregate : "article", pipeline : [
{ $project : {
_id : 0,
author : 1,
commentsAuthor : "$comments.author"
}}
]});
var p9result = [
{
"author" : "bob",
"commentsAuthor" : [
"joe",
"sam"
]
},
{
"author" : "dave",
"commentsAuthor" : [
"barbara",
"jenny"
]
},
{
"author" : "jane",
"commentsAuthor" : [
"will",
"jenny"
]
}
];
assert.docEq(p9.result, p9result, 'p9 failed');
// simple sort
var p10 = db.runCommand(
{ aggregate : "article", pipeline : [
{ $sort : { title : 1 }
}
]});
var p10result = [
{
"_id" : 1,
"title" : "this is my title",
"author" : "bob",
"posted" : ISODate("2004-03-21T18:59:54Z"),
"pageViews" : 5,
"tags" : [
"fun",
"good",
"fun"
],
"comments" : [
{
"author" : "joe",
"text" : "this is cool"
},
{
"author" : "sam",
"text" : "this is bad"
}
],
"other" : {
"foo" : 5
}
},
{
"_id" : 3,
"title" : "this is some other title",
"author" : "jane",
"posted" : ISODate("2000-12-31T05:17:14Z"),
"pageViews" : 6,
"tags" : [
"nasty",
"filthy"
],
"comments" : [
{
"author" : "will",
"text" : "i don't like the color"
},
{
"author" : "jenny",
"text" : "can i get that in green?"
}
],
"other" : {
"bar" : 14
}
},
{
"_id" : 2,
"title" : "this is your title",
"author" : "dave",
"posted" : ISODate("2030-08-08T04:11:10Z"),
"pageViews" : 7,
"tags" : [
"fun",
"nasty"
],
"comments" : [
{
"author" : "barbara",
"text" : "this is interesting"
},
{
"author" : "jenny",
"text" : "i like to play pinball",
"votes" : 10
}
],
"other" : {
"bar" : 14
}
}
];
assert.docEq(p10.result, p10result, 'p10 failed');
// unwind on nested array
db.p11.drop();
db.p11.save( {
_id : 5,
name : 'MongoDB',
items : {
authors : ['jay', 'vivek', 'bjornar'],
dbg : [17, 42]
},
favorites : ['pickles', 'ice cream', 'kettle chips']
});
var p11 = db.runCommand(
{ aggregate : "p11", pipeline : [
{ $unwind : "$items.authors" },
{ $project : {
name : 1,
author : "$items.authors"
}},
]});
p11result = [
{
"_id" : 5,
"name" : "MongoDB",
"author" : "jay"
},
{
"_id" : 5,
"name" : "MongoDB",
"author" : "vivek"
},
{
"_id" : 5,
"name" : "MongoDB",
"author" : "bjornar"
}
];
assert.docEq(p11.result, p11result, 'p11 failed');
// multiply test
var p12 = db.runCommand(
{ aggregate : "article", pipeline : [
{ $project : {
theProduct : { $multiply:["$pageViews",
{ $ifNull:["$other.foo",
"$other.bar"] } ] }
}}
]});
var p12result = [
{
"_id" : 1,
"theProduct" : 25
},
{
"_id" : 2,
"theProduct" : 98
},
{
"_id" : 3,
"theProduct" : 84
}
];
assert.docEq(p12.result, p12result, 'p12 failed');
// subtraction test
var p13 = db.runCommand(
{ aggregate : "article", pipeline : [
{ $project : {
theDifference : { $subtract:["$pageViews",
{ $ifNull:["$other.foo",
"$other.bar"] } ] }
}}
]});
var p13result = [
{
"_id" : 1,
"theDifference" : 0
},
{
"_id" : 2,
"theDifference" : -7
},
{
"_id" : 3,
"theDifference" : -8
}
];
assert.docEq(p13.result, p13result, 'p13 failed');
// mod test
var p14 = db.runCommand(
{ aggregate : "article", pipeline : [
{ $project : {
theRemainder : { $mod:[
{ $ifNull:["$other.foo",
"$other.bar"] },
"$pageViews", ] }
}}
]});
var p14result = [
{
"_id" : 1,
"theRemainder" : 0
},
{
"_id" : 2,
"theRemainder" : 0
},
{
"_id" : 3,
"theRemainder" : 2
}
];
assert.docEq(p14.result, p14result, 'p14 failed');
// toUpper test
var p15 = db.runCommand(
{ aggregate : "article", pipeline : [
{ $project : {
author : {$toUpper: "$author"},
pageViews : 1
}}
]});
var p15result = [
{
"_id" : 1,
"author" : "BOB",
"pageViews" : 5
},
{
"_id" : 2,
"author" : "DAVE",
"pageViews" : 7
},
{
"_id" : 3,
"author" : "JANE",
"pageViews" : 6
}
];
assert.docEq(p15.result, p15result, 'p15 failed');
// toLower test
var p16 = db.runCommand(
{ aggregate : "article", pipeline : [
{ $project : {
author : {$toUpper: "$author"},
pageViews : 1
}},
{ $project : {
author : {$toLower: "$author"},
pageViews : 1
}}
]});
var p16result = [
{
"_id" : 1,
"author" : "bob",
"pageViews" : 5,
},
{
"_id" : 2,
"author" : "dave",
"pageViews" : 7,
},
{
"_id" : 3,
"author" : "jane",
"pageViews" : 6,
}
];
assert.docEq(p16.result, p16result, 'p16 failed');
// substr test
var p17 = db.runCommand(
{ aggregate : "article", pipeline : [
{ $project : {
author : {$substr: ["$author", 1, 2]},
}}
]});
var p17result = [
{
"_id" : 1,
"author" : "ob"
},
{
"_id" : 2,
"author" : "av"
},
{
"_id" : 3,
"author" : "an"
}
];
assert.docEq(p17.result, p17result, 'p17 failed');
// strcasecmp test
var p18 = db.runCommand(
{aggregate : "article", pipeline : [
{ $project : {
tags : 1,
thisisalametest : {$strcasecmp: ["foo","bar"]},
thisisalamepass : {$strcasecmp: ["foo","foo"]}
}}
]});
var p18result = [
{
"_id" : 1,
"tags" : [
"fun",
"good",
"fun"
],
"thisisalametest" : 1,
"thisisalamepass" : 0
},
{
"_id" : 2,
"tags" : [
"fun",
"nasty"
],
"thisisalametest" : 1,
"thisisalamepass" : 0
},
{
"_id" : 3,
"tags" : [
"nasty",
"filthy"
],
"thisisalametest" : 1,
"thisisalamepass" : 0
}
];
assert.docEq(p18.result, p18result, 'p18 failed');
// date tests
var p19 = db.runCommand({aggregate : "article", pipeline : [
{ $project : {
authors: 1,
posted: 1,
seconds: {$second: "$posted"},
minutes: {$minute: "$posted"},
hour: {$hour: "$posted"},
dayOfYear: {$dayOfYear: "$posted"},
dayOfMonth: {$dayOfMonth: "$posted"},
dayOfWeek: {$dayOfWeek: "$posted"},
month: {$month: "$posted"},
week: {$week: "$posted"},
year: {$year: "$posted"}
}}
]});
var p19result = [
{
"_id" : 1,
"posted" : ISODate("2004-03-21T18:59:54Z"),
"seconds" : 54,
"minutes" : 59,
"hour" : 18,
"dayOfYear" : 81,
"dayOfMonth" : 21,
"dayOfWeek" : 1,
"month" : 3,
"week" : 12,
"year" : 2004,
},
{
"_id" : 2,
"posted" : ISODate("2030-08-08T04:11:10Z"),
"seconds" : 10,
"minutes" : 11,
"hour" : 4,
"dayOfYear" : 220,
"dayOfMonth" : 8,
"dayOfWeek" : 5,
"month" : 8,
"week" : 31,
"year" : 2030,
},
{
"_id" : 3,
"posted" : ISODate("2000-12-31T05:17:14Z"),
"seconds" : 14,
"minutes" : 17,
"hour" : 5,
"dayOfYear" : 366,
"dayOfMonth" : 31,
"dayOfWeek" : 1,
"month" : 12,
"week" : 53,
"year" : 2000,
}
];
assert.docEq(p19.result, p19result, 'p19 failed');
db.vartype.drop();
db.vartype.save({ x : 17, y : "foo"});
// ternary conditional operator
var p21 = db.runCommand(
{ aggregate : "article", pipeline : [
{ $project : {
_id : 0,
author : 1,
pageViews : { $cond : [ {$eq:["$author", "dave"]},
{$add:["$pageViews", 1000]}, "$pageViews" ]
}
}}
]});
var p21result = [
{
"author" : "bob",
"pageViews" : 5
},
{
"author" : "dave",
"pageViews" : 1007
},
{
"author" : "jane",
"pageViews" : 6
}
];
assert.docEq(p21.result, p21result, 'p21 failed');
// simple matching
var m1 = db.runCommand(
{ aggregate : "article", pipeline : [
{ $match : { author : "dave" } }
]});
var m1result = [
{
"_id" : 2,
"title" : "this is your title",
"author" : "dave",
"posted" : ISODate("2030-08-08T04:11:10Z"),
"pageViews" : 7,
"tags" : [
"fun",
"nasty"
],
"comments" : [
{
"author" : "barbara",
"text" : "this is interesting"
},
{
"author" : "jenny",
"text" : "i like to play pinball",
"votes" : 10
}
],
"other" : {
"bar" : 14
}
}
];
assert.docEq(m1.result, m1result, 'm1 failed');
// combining matching with a projection
var m2 = db.runCommand(
{ aggregate : "article", pipeline : [
{ $project : {
title : 1,
author : 1,
pageViews : 1,
tags : 1,
comments : 1
}},
{ $unwind : "$tags" },
{ $match : { tags : "nasty" } }
]});
var m2result = [
{
"_id" : 2,
"title" : "this is your title",
"author" : "dave",
"pageViews" : 7,
"tags" : "nasty",
"comments" : [
{
"author" : "barbara",
"text" : "this is interesting"
},
{
"author" : "jenny",
"text" : "i like to play pinball",
"votes" : 10
}
]
},
{
"_id" : 3,
"title" : "this is some other title",
"author" : "jane",
"pageViews" : 6,
"tags" : "nasty",
"comments" : [
{
"author" : "will",
"text" : "i don't like the color"
},
{
"author" : "jenny",
"text" : "can i get that in green?"
}
]
}
];
assert.docEq(m2.result, m2result, 'm2 failed');
// group by tag, _id is a field reference
var g1 = db.runCommand(
{ aggregate : "article", pipeline : [
{ $project : {
author : 1,
tags : 1,
pageViews : 1
}},
{ $unwind : "$tags" },
{ $group : {
_id : "$tags",
docsByTag : { $sum : 1 },
viewsByTag : { $sum : "$pageViews" }
}},
{$sort: {'_id': 1}}
]});
var g1result = [
{
"_id" : "filthy",
"docsByTag" : 1,
"viewsByTag" : 6
},
{
"_id" : "fun",
"docsByTag" : 3,
"viewsByTag" : 17
},
{
"_id" : "good",
"docsByTag" : 1,
"viewsByTag" : 5
},
{
"_id" : "nasty",
"docsByTag" : 2,
"viewsByTag" : 13
},
];
assert.docEq(g1.result, g1result, 'g1 failed');
// $max, and averaging in a final projection; _id is structured
var g2 = db.runCommand(
{ aggregate : "article", pipeline : [
{ $project : {
author : 1,
tags : 1,
pageViews : 1
}},
{ $unwind : "$tags" },
{ $group : {
_id: { tags : "$tags" },
docsByTag : { $sum : 1 },
viewsByTag : { $sum : "$pageViews" },
mostViewsByTag : { $max : "$pageViews" },
}},
{ $project : {
_id: false,
tag : "$_id.tags",
mostViewsByTag : 1,
docsByTag : 1,
viewsByTag : 1,
avgByTag : { $divide:["$viewsByTag", "$docsByTag"] }
}},
{$sort: {'docsByTag': 1, 'viewsByTag': 1}}
]});
var g2result = [
{
"docsByTag" : 1,
"viewsByTag" : 5,
"mostViewsByTag" : 5,
"tag" : "good",
"avgByTag" : 5
},
{
"docsByTag" : 1,
"viewsByTag" : 6,
"mostViewsByTag" : 6,
"tag" : "filthy",
"avgByTag" : 6
},
{
"docsByTag" : 2,
"viewsByTag" : 13,
"mostViewsByTag" : 7,
"tag" : "nasty",
"avgByTag" : 6.5
},
{
"docsByTag" : 3,
"viewsByTag" : 17,
"mostViewsByTag" : 7,
"tag" : "fun",
"avgByTag" : 5.666666666666667
}
];
assert.docEq(g2.result, g2result, 'g2 failed');
// $push as an accumulator; can pivot data
var g3 = db.runCommand(
{ aggregate : "article", pipeline : [
{ $project : {
author : 1,
tags : 1,
}},
{ $unwind : "$tags" },
{ $group : {
_id : { tags : "$tags" },
authors : { $push : "$author" }
}},
{$sort: {'_id': 1}}
]});
var g3result = [
{
"_id" : {
"tags" : "filthy"
},
"authors" : [
"jane"
]
},
{
"_id" : {
"tags" : "fun"
},
"authors" : [
"bob",
"bob",
"dave"
]
},
{
"_id" : {
"tags" : "good"
},
"authors" : [
"bob"
]
},
{
"_id" : {
"tags" : "nasty"
},
"authors" : [
"dave",
"jane"
]
}
];
assert.docEq(g3.result, g3result, 'g3 failed');
// $avg, and averaging in a final projection
var g4 = db.runCommand(
{ aggregate : "article", pipeline : [
{ $project : {
author : 1,
tags : 1,
pageViews : 1
}},
{ $unwind : "$tags" },
{ $group : {
_id: { tags : "$tags" },
docsByTag : { $sum : 1 },
viewsByTag : { $sum : "$pageViews" },
avgByTag : { $avg : "$pageViews" },
}},
{$sort: {'_id': 1}}
]});
var g4result = [
{
"_id" : {
"tags" : "filthy"
},
"docsByTag" : 1,
"viewsByTag" : 6,
"avgByTag" : 6
},
{
"_id" : {
"tags" : "fun"
},
"docsByTag" : 3,
"viewsByTag" : 17,
"avgByTag" : 5.666666666666667
},
{
"_id" : {
"tags" : "good"
},
"docsByTag" : 1,
"viewsByTag" : 5,
"avgByTag" : 5
},
{
"_id" : {
"tags" : "nasty"
},
"docsByTag" : 2,
"viewsByTag" : 13,
"avgByTag" : 6.5
}
];
assert.docEq(g4.result, g4result, 'g4 failed');
// $addToSet as an accumulator; can pivot data
var g5 = db.runCommand(
{ aggregate : "article", pipeline : [
{ $project : {
author : 1,
tags : 1,
}},
{ $unwind : "$tags" },
{ $group : {
_id : { tags : "$tags" },
authors : { $addToSet : "$author" }
}},
{$sort: {'_id': 1}}
]});
// $addToSet doesn't guarantee order so we shouldn't test for it.
g5.result.forEach(function(obj) {
obj.authors.sort();
});
var g5result = [
{
"_id" : {
"tags" : "filthy"
},
"authors" : [
"jane"
]
},
{
"_id" : {
"tags" : "fun"
},
"authors" : [
"bob",
"dave",
]
},
{
"_id" : {
"tags" : "good"
},
"authors" : [
"bob"
]
},
{
"_id" : {
"tags" : "nasty"
},
"authors" : [
"dave",
"jane",
]
}
];
assert.docEq(g5.result, g5result, 'g5 failed');
// $first and $last accumulators, constant _id
var g6 = db.runCommand(
{ aggregate : "article", pipeline : [
{ $sort : { author : -1 } },
{ $group : {
_id : "authors", /* constant string, *not* a field reference */
firstAuthor : { $last : "$author" }, /* note reverse sort above */
lastAuthor : { $first : "$author" }, /* note reverse sort above */
count : { $sum : 1 }
}}
]});
var g6result = [
{
"_id" : "authors",
firstAuthor : "bob",
lastAuthor : "jane",
count : 3
}
];
// Test unwind on an unused field
var g7 = db.runCommand(
{ aggregate : "article", pipeline : [
{ $unwind : '$tags' },
{ $group : {
_id : "tag_count", /* constant string, *not* a field reference */
count : { $sum : 1 }
}}
]});
assert.eq(g7.result[0].count, 7);