在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
1. 聚合框架 db.test_collection.aggregate({"$project" : {"name" : 1}}); => { "_id" : ObjectId("535a2d3c169097010b92fdf6"), "name" : "snake" } 2){"$group", {"_id" : "$name", "count" : {"$sum" : 1}}} db.test_collection.aggregate({"$project" : {"name" : 1}}, {"$group" : {"_id" : "$name", "count" : {"$sum" : 1}}}); => { "_id" : "bird", "count" : 8344 } { "_id" : "snake", "count" : 8443 } { "_id" : "cat", "count" : 8183 } { "_id" : "rabbit", "count" : 8206 } { "_id" : "tiger", "count" : 8329 } { "_id" : "cow", "count" : 8309 } { "_id" : "horse", "count" : 8379 } { "_id" : "dog", "count" : 8406 } { "_id" : "dragon", "count" : 8372 } { "_id" : "elephant", "count" : 8264 } { "_id" : "pig", "count" : 8403 } { "_id" : "lion", "count" : 8362 } 3){"$sort" : {"count" : -1}} db.test_collection.aggregate( { "$project" : {"name" : 1}}, {"$group" : {"_id" : "$name", "count" : {"$sum" : 1}}}, {"$sort" : {"count" : -1}}, {"$limit" : 5} ); aggregate会返回一个文档数组,内容为出现次数最多的5个动物: { "_id" : "snake", "count" : 8443 } { "_id" : "dog", "count" : 8406 } { "_id" : "pig", "count" : 8403 } { "_id" : "horse", "count" : 8379 } { "_id" : "dragon", "count" : 8372 } 调试过程中。可以逐一对管道符进行排查。 2. 管道操作符 2.1 $match 2.2 $project db.foo.aggregate({"$project" : {"city" : 1, "_id" : 0}}) => { "city" : "NEW WORK" } 可以将投射过的字段重命名: db.foo.aggregate({"$project" : {"newcity" : "$city", "_id" : 0}}) => { "newcity" : "NEW WORK" } 使用"$fieldname"语法为了在聚合框架中引用fieldname字段,例如上面"$city"会被替换为"NEW WORK"。 db.foo.aggregate( {"$project" : {"total" : {"$add" : ["$age", "$year"]}, "_id" : 0 } } ) {"total" : 15} 可以将多个表达式组合为更为复杂的表达式: db.foo.aggregate( {"$project" : {"sub" : {"$subtract" : [{"$add" : ["$age", "$year"]}, 7]}, "_id" : 0 } } ) { "sub" : 8 } 操作符语法: 2.2.3 日期表达式 db.bar.insert({"name" : "pipi", "date" : new Date()}) db.bar.aggregate( {"$project" : {"birth-month" : {"$month" : "$date"}, "_id" : 0 } } ) { "birth-month" : 4 } 也可以使用字面量日期。 db.bar.aggregate( {"$project" : {"up-to-now" : {"$subtract" : [{"$minute" : new Date()}, {"$minute" : "$date"}]}, "_id" : 0 } } ) { "up-to-now" : 18 } 2.2.3 字符串表达式 db.foo.insert({"firstname" : "caoqing", "lastname" : "lucifer"}) db.foo.aggregate( { "$project" : { "email" : { "$concat" : [ {"$substr" : ["$firstname", 0, 1]}, ".", "$lastname", "@gmail.com" ] }, "_id" : 0 } } ) { "email" : "[email protected]" } 2.2.3 逻辑表达式 "$crond" : [booleanExpr, trueExpr, falseExpr] 如果为true,返回trueExpr,否则,返回falseExpr。 "$ifFull" : [expr, replacementExpr] 如果expr为null,返回replacementExpr,否则返回expr。 db.bar.insert( { "name" : "xiaobao", "teachersPet" : 1, "attendance" : 90, "quizz" : 80, "test" : 85 } ) db.bar.insert( { "name" : "caoqing", "teachersPet" : 0, "attendance" : 20, "quizz" : 50, "test" : 90 } ) db.bar.insert( { "name" : "pipi", "teachersPet" : 0, "attendance" : 100, "quizz" : 50, "test" : 10 } ) 聚合: db.bar.aggregate( { "$project" : { "grade" : { "$cond" : [ "$teachersPet", 100, { "$add" : [ {"$multiply" : [0.1, "$attendance"]}, {"$multiply" : [0.3, "$quizz"]}, {"$multiply" : [0.6, "$test"]}, ] } ] }, "_id" : 0 } } ) 返回结果: { "grade" : 100 } { "grade" : 71 } { "grade" : 31 } 3. MapReduce 3.1 找出集合中的所有键 map = function() { emit(this.country, {count : 1}); } reduce接受两个参数,一个是key,就是emit返回的第一个值,还有一个数组,由一个或多个键对应的{count : 1}文档组成。 reduce = function(key, value) { var result = {count : 0}; for (var i = 0; i < value.length; i++) { result.count += value[i].count; } return result; } 示例表数据: { "_id" : 38, "country" : "japan", "money" : 724 } { "_id" : 39, "country" : "germany", "money" : 520 } { "_id" : 40, "country" : "india", "money" : 934 } { "_id" : 41, "country" : "china", "money" : 721 } { "_id" : 42, "country" : "germany", "money" : 156 } { "_id" : 43, "country" : "canada", "money" : 950 } { "_id" : 44, "country" : "india", "money" : 406 } { "_id" : 45, "country" : "japan", "money" : 776 } { "_id" : 46, "country" : "canada", "money" : 468 } { "_id" : 47, "country" : "germany", "money" : 262 } { "_id" : 48, "country" : "germany", "money" : 126 } { "_id" : 49, "country" : "japan", "money" : 86 } { "_id" : 50, "country" : "canada", "money" : 870 } { "_id" : 51, "country" : "india", "money" : 98 } { "_id" : 52, "country" : "india", "money" : 673 } { "_id" : 53, "country" : "japan", "money" : 487 } { "_id" : 54, "country" : "india", "money" : 681 } { "_id" : 55, "country" : "canada", "money" : 491 } { "_id" : 56, "country" : "japan", "money" : 98 } { "_id" : 57, "country" : "china", "money" : 172 } 运行结果: db.foo.mapReduce(map, reduce, {out : "collection"}) { "result" : "collcetion", "timeMillis" : 83, "counts" : { "input" : 99, "emit" : 99, "reduce" : 5, "output" : 5 }, "ok" : 1, "$gleStats" : { "lastOpTime" : Timestamp(1399168165, 15), "electionId" : ObjectId("535a2ce15918f42de9ab1427") }, } (1)result:存放的集合名 db.collection.find(); { "_id" : "canada", "value" : { "count" : 19 } } { "_id" : "china", "value" : { "count" : 15 } } { "_id" : "germany", "value" : { "count" : 25 } } { "_id" : "india", "value" : { "count" : 20 } } { "_id" : "japan", "value" : { "count" : 20 } } 3.2 MapRecude其他的键 4 聚合命名 db.foo.count() => 99 可以传入一个查询文档: db.foo.count({country : "china"}) => 15 增加查询条件会使count变慢。 db.runCommand({ "distinct" : "foo", "key" : "country"}) => { "values" : [ "japan", "germany", "india", "china", "canada" ], "stats" : { "n" : 99, "nscanned" : 99, "nscannedObjects" : 99, "timems" : 22, "cursor" : "BasicCursor" }, "ok" : 1, "$gleStats" : { "lastOpTime" : Timestamp(1399171995, 15), "electionId" : ObjectId("535a2ce15918f42de9ab1427") } } 4.3 group var name = ["Caoqing", "Spider-man", "Garfield"] for (var i = 0; i < 10000; i++) { iname = name[Math.floor(Math.random() * name.length)]; date = new Date().getTime(); number = Math.floor(100 * Math.random()); db.coll.insert({_id : i, name : iname, time : date, age : number}); } 生成的列表中包含最新的时间和最新的时间对应的年纪。 db.runCommand({"group" : { "ns" : "coll", "key" : {"name" : true}, "initial" : {"time" : 0}, "$reduce" : function(doc, prev) { if (doc.time > prev.time) { prev.age = doc.age; prev.time = doc.time; } } }}) (1)"ns" : "coll" "$reduce" : function(doc, prev) {...} { "retval" : [ { "name" : "Spider-man", "time" : 1399179398567, "age" : 55 }, { "name" : "Garfield", "time" : 1399179398565, "age" : 85 }, { "name" : "Caoqing", "time" : 1399179398566, "age" : 86 } ], "count" : 10000, "keys" : 3, "ok" : 1, "$gleStats" : { "lastOpTime" : Timestamp(1399179362, 1), "electionId" : ObjectId("535a2ce15918f42de9ab1427") } } 如果有文档不存在指定分组的键,这些文档会单独分为一组,缺失的键会使用name:null这样的形式。如下: db.coll.insert({age : 5, time : new Date().getTime()}) 返回结果: ... { "name" : null, "time" : 1399180685288, "age" : 5 } "count" : 10001, "keys" : 4, ... 为了排除不包含指定用于分组的键的文档,可以在"condition"中加入"name":{"$exists" : true}。 db.runCommand({"group" : { "ns" : "coll", "key" : {"name" : true}, "initial" : {"time" : 0}, "$reduce" : function(doc, prev) { if (doc.time > prev.time) { prev.age = doc.age; prev.time = doc.time; } }, "condition" : {"name" : {"$exists" : true}} }}) 4.3.1 使用完成器 db.foo.group({ "ns" : "foo", "$keyf" : function(x) { return x.category.toLowerCase(); }; "initial" : ..., ...... }) |
请发表评论