时间:2021-07-01 10:21:17 帮助过:7人阅读
先吐个槽,公司的Mongo版本是2.6.4,而用的java驱动包版本是超级老物2.4版。当时一个“如何对分组后的文档进行筛选”这个需求头痛了很久,虽然shell命令下可以使用Aggregation很方便地解决,但是java驱动包从2.9.0版本才开始支持该特性,我至今没有找到不用Aggregation解决上述需求的办法。只能推荐公司升级驱动包版本,希望没有后续的兼容问题。
Mongo2.2版本后开始支持Aggregation Pipeline(http://docs.mongodb.org/manual/core/aggregation-pipeline/),而java驱动包从2.9.0版本才开始支持2.2的特性,2.9版本是12年发布的,mongodb在09年就出现了,可见Mongo对java的开发者似乎不怎么友好←_←
话扯到这里,接下来就对我这一周所学的Mongo做一个总结,错误之处还望指教 :-D。
MongoDB目前提供了三个可以执行聚合操作的命令:aggregate、mapReduce、group。三者在性能和操作的优劣比较见官网提供的表格http://docs.mongodb.org/manual/reference/aggregation-commands-comparison/,这里不再赘述细节,先说一下这三个函数的原型及底层封装的命令。
三者在性能和操作的优劣比较见官网提供的表格http://docs.mongodb.org/manual/reference/aggregation-commands-comparison/,这里不再赘述细节,先说一下这三个函数的原型及底层封装的命令。
函数名 |
函数原型 |
封装的命令 |
db.collection.group() |
db.collection.group( { key, reduce, initial [, keyf] [, cond] [, finalize] } ) |
db.runCommand( { group: { ns: <namespace>, key: <key>, $reduce: <reduce function>, $keyf: <key function>, cond: <query>, finalize: <finalize function> } } ) |
db.collection.mapReduce() |
db.collection.mapReduce( <map>, <reduce>, { out: <collection>, query: <document>, sort: <document>, limit: <number>, finalize: <function>, scope: <document>, jsMode: <boolean>, verbose: <boolean> } ) |
db.runCommand( { mapReduce: <collection>, map: <function>, reduce: <function>, finalize: <function>, out: <output>, query: <document>, sort: <document>, limit: <number>, scope: <document>, jsMode: <boolean>, verbose: <boolean> } ) |
db.collection.aggregate() |
db.collection.aggregate( pipeline, options ) |
db.runCommand( { aggregate: "<collection>", pipeline: [ <stage>, <...> ], explain: <boolean>, allowDiskUse: <boolean>, cursor: <document> } ) |
好记性不如烂笔头,下面通过操作来了解这几个函数和命令
先准备SQL的测试数据,用来验证结果、比较SQL语句和NoSQL的异同,测试环境是mysql
先创建数据库表
create table dogroup (
_id int,
name varchar(45),
course varchar(45),
score int,
gender int,
primary key(_id)
);
插入数据
insert into dogroup (_id, name, course, score, gender) values (1, "N", "C", 5, 0);
insert into dogroup (_id, name, course, score, gender) values (2, "N", "O", 4, 0);
insert into dogroup (_id, name, course, score, gender) values (3, "A", "C", 5, 1);
insert into dogroup (_id, name, course, score, gender) values (4, "A", "O", 6, 1);
insert into dogroup (_id, name, course, score, gender) values (5, "A", "U", 8, 1);
insert into dogroup (_id, name, course, score, gender) values (6, "A", "R", 8, 1);
insert into dogroup (_id, name, course, score, gender) values (7, "A", "S", 7, 1);
insert into dogroup (_id, name, course, score, gender) values (8, "M", "C", 4, 0);
insert into dogroup (_id, name, course, score, gender) values (9, "M", "U", 7, 0);
insert into dogroup (_id, name, course, score, gender) values (10, "E", "C", 7, 1);
准备MongoDB测试数据
创建Collection(等同于SQL中的表,该行可以不写,Mongo会在插入数据时自动创建Collection)
db.createCollection("dogroup")
插入数据
db.dogroup.insert({"_id": 1,"name": "N",course: "C","score": 5,gender: 0})
db.dogroup.insert({"_id": 2,"name": "N",course: "O","score": 4,gender: 0})
db.dogroup.insert({"_id": 3,"name": "A",course: "C","score": 5,gender: 1})
db.dogroup.insert({"_id": 4,"name": "A",course: "O","score": 6,gender: 1})
db.dogroup.insert({"_id": 5,"name": "A",course: "U","score": 8,gender: 1})
db.dogroup.insert({"_id": 6,"name": "A",course: "R","score": 8,gender: 1})
db.dogroup.insert({"_id": 7,"name": "A",course: "S","score": 7,gender: 1})
db.dogroup.insert({"_id": 8,"name": "M",course: "C","score": 4,gender: 0})
db.dogroup.insert({"_id": 9,"name": "M",course: "U","score": 7,gender: 0})
db.dogroup.insert({"_id": 10,"name": "E",course: "C","score": 7,gender: 1})
以下操作可能逻辑上没有实际意义,主要是帮助熟悉指令
1、查询出共有几门课程(course),返回的格式为“课程名、数量”
SQL写法:select course as ‘课程名‘, count(*) as ‘数量‘ from dogroup group by course;
MongoDB写法:
① group方式
db.dogroup.group({
key : { course: 1 },
initial : { count: 0 },
reduce : function Reduce(curr, result) {
result.count += 1;
},
finalize : function Finalize(out) {
return {"课程名": out.