06-使用聚合表达式运算符
9.2.3 使用聚合表达式运算符
在MongoDB shell中使用聚合流水线来操作结果 在本节中,您将编写一个简单的MongoDB shell脚本,它使用聚合流水线来操作从MongoDB示例数据集返回的数据。通过这个示例,您将熟悉如何使用Collection对象的方法aggregate()。程序清单9.3显示了这个示例的代码。 在这个示例的第4~16行,使用了$match运算符来获取以元音字母打头的单词,然后使用$group运算符计算各组单词的最大和最小长度。接下来,使用运算符$sort对结果排序,再显示结果。 在第17~25行,使用了$match运算符来找出长度为4的单词,再使用运算符$limit将文档数限制为5个。然后,使用$project运算符来创建新文档,这些文档包含原始文档的word字段和stats字段,但将word字段重命名为_id。 在第26~34行,使用了$group运算符根据第一个字母将单词分组,并使用运算符$avg计算各组单词的平均长度。注意到指定first字段时,在字段名前加上了$($first)。接下来,使用运算符$sort对结果排序。最后,使用$limit运算符限制结果,使其只包含5个文档,并显示这些文档。 请执行如下步骤,创建并运行这个对示例数据集中的文档执行聚合并显示结果的MongoDB shell脚本。 1.确保启动了MongoDB服务器。 2.确保运行了生成数据库words的脚本文件code/hour05/generate_words.js。 3.在文件夹code/hour09中新建一个文件,并将其命名为doc_aggregate.js。 4.在这个文件中输入程序清单程序清单9.3所示的代码。这些代码连接到数据库words,获取表示集合word_stats的Collection对象,并使用aggregate()对单词集执行聚合。 5.将这个文件存盘。 6.打开一个控制台窗口,并切换到目录code/hour09。 7.执行下面的命令以运行这个脚本,它对集合word_stats中的单词执行聚合并显示结果。程序清单9.4显示了这个脚本的输出。 程序清单9.3 doc_aggregate.js:使用MongoDB shell聚合集合中的文档 程序清单9.4 doc_aggregate.js-output:使用MongoDB shell聚合集合中文档的输出 ▲
使用聚合运算符时,将创建新文档,这些文档将传递给聚合流水线的下一个阶段。MongoDB聚合框架提供了很多表达式运算符,可用于计算新字段的值以及对文档中的既有字段进行比较。
使用聚合运算符$group时,新文档定义的字段将对应于多个原始文档。MongoDB提供了一组运算符,可用于对原始文档的字段执行计算,以得到新文档的字段值。例如,设置新文档的字段maximumt,使其表示相应分组中原始文档的最大value字段值。表9.2列出了可在聚合运算符$group中使用的表达式运算符。
| 运算符 | 描述 | | :----- | :----- | :----- | :----- | | $addToSet | 返回一个数组,包含当前文档组中指定字段的不同值,如colors: {$addToSet: "$color"} | | $first | 返回当前文档组中第一个文档的指定字段的值,如firstValue:{$first: "$value"} | | $last | 返回当前文档组中最后一个文档的指定字段的值,如lastValue:{$last: "$value"} | | $max | 返回当前文档组中指定字段的最大值,如maxValue:{$max: "$value"} | | $min | 返回当前文档组中指定字段的最小值,如minValue:{$min: "$value"} | | $avg | 返回当前文档组中指定字段的平均值,如aveValue:{$avg: "$value"} | | $push | 返回一个数组,包含当前文档组中每个文档的指定字段值,如username:{$push: "$username"} | | $sum | 返回当前文档组中各个文档的指定字段值之和,如total:{$sum: "$value"} |
计算新字段的值时,还可使用多个字符串运算符和算术运算符。表9.3列出了在聚合运算符中计算新字段的值时,较为常用的一些表达式运算符。
| 运算符 | 描述 | | :----- | :----- | :----- | :----- | | $add | 将一系列数字相加,如valuePlus5:{$add:["$value", 5] } | | $divide | 接受两个数字,并将第一个数字与第二个数字相除,如valueDividedBy5:{$divide:["$value", 5] } | | $mod | 接受两个数字,并计算第一个数字除以第二个数字的余数,如valueMod5:{$mod:["$value", 5] } | | $multiply | 计算一系列数字的乘积,如valueTimes5:{$multiply:["$value", 5] } | | $subtract | 接受两个数字,并将第一个数字与第二个数字相减,如valueMinus5:{$subtract:["$value", 5] } | | $concat | 拼接多个字符串,如title:{$concat:["$title", " ", "$name"] } | | $strcasecmp | 比较两个字符串,并返回一个指出比较结果的整数,如isTest:{$strcasecmp:["$value", "test"] } | | $substr | 返回字符串的指定部分,如hasTest:{$substr:["$value", "test"] } | | $toLower | 将字符串转换为小写,如titleLower:{$toLower:"$title"} | | $toUpper | 将字符串转换为大写,如titleUpper:{$toUpper:"$title"} |
▼ Try It Yourself
mongo doc_aggregate.js
01 mongo = new Mongo('localhost');
02 wordsDB = mongo.getDB('words');
03 wordsColl = wordsDB.getCollection('word_stats');
04 results = wordsColl.aggregate(
05 { $match: {first:{$in:['a','e','i','o','u']}}},
06 { $group: { _id:"$first",
07 largest:{$max:"$size"},
08 smallest:{$min:"$size"},
09 total:{$sum:1}}},
10 { $sort: {_id:1}}
11 );
12 print("Largest and smallest word sizes for " +
13 "words beginning with a vowel: ");
14 results.result.forEach(function(item){
15 print(JSON.stringify(item));
16 });
17 results = wordsColl.aggregate(
18 {$match: {size:4}},
19 {$limit: 5},
20 {$project: {_id:"$word", stats:1}}
21 );
22 print("Stats for 5 four letter words: ");
23 results.result.forEach(function(item){
24 print(JSON.stringify(item));
25 });
26 results = wordsColl.aggregate(
27 {$group: {_id:"$first", average:{$avg:"$size"}}},
28 {$sort: {average:-1}},
29 {$limit: 5}
30 );
31 print("First letter of top 6 largest average word size: ");
32 results.result.forEach(function(item){
33 print(JSON.stringify(item));
34 });
Largest and smallest word sizes for words beginning with a vowel:
{"_id":"a","largest":14,"smallest":1,"total":192}
{"_id":"e","largest":13,"smallest":3,"total":150}
{"_id":"i","largest":14,"smallest":1,"total":114}
{"_id":"o","largest":12,"smallest":2,"total":72}
{"_id":"u","largest":13,"smallest":2,"total":33}
Stats for 5 four letter words:
{"_id":"have","stats":{"vowels":2,"consonants":2}}
{"_id":"that","stats":{"vowels":1,"consonants":3}}
{"_id":"with","stats":{"vowels":1,"consonants":3}}
{"_id":"this","stats":{"vowels":1,"consonants":3}}
{"_id":"they","stats":{"vowels":1,"consonants":3}}
First letter of top 6 largest average word size:
{"_id":"i","average":7.947368421052632}
{"_id":"e","average":7.42}
{"_id":"c","average":7.292134831460674}
{"_id":"p","average":6.881818181818182}
{"_id":"r","average":6.767123287671233}