一、数据库操作

切换数据库

use database_name

use school

注:如果数据库存在,则切换到该数据库下,如果此数据库还不存在,也可以切过来,但是并不能立刻创建该数据库

查看所有得数据库

show dbs

备注:刚创建的数据库shcool如果不在查询的列表中,如果要显示它,则需要向school中插入数据

db.students.insert({age:1})

查看当前使用的数据库

db

删除数据库

db.dropDatabase()

二、集合操作

查看集合帮助

use demo

db.demo.help()

创建集合

db.createCollection(collection_name)

创建集合并插入一个文档

db.collection_name.insert({document})

//例如

db.demo.insert({age:1})

注:上图里的ObjectId是有规律的,规律如下

之前我们使用MySQL等关系型数据库时,主键都是设置成自增的。但在分布式环境下,这种方法就不可行了,会产生冲突。为此,MongoDB采用了一个称之为ObjectId的类型来做主键。ObjectId是一个12字节的 BSON 类型字符串。按照字节顺序,依次代表:

-

-

4字节:

UNIX时间戳

3字节:

表示运行MongoDB的机器

2字节:

表示生成此_id的进程

3字节:

由一个随机数开始的计数器生成的值

查看当前数据库下的集合

show collections

删除当前集合

db.collection_name.drop() 例如: db.demo.drop()

文档操作

插入文档

insert

db.collection_name.insert({document})

collection_name:集合的名字

document 插入的文档(数据)

注:每当插入一条新文档的时候mongodb会自动为此文档生成一个_id属性,_id属性是唯一的,用来标识一个文档,_id也可以直接指定,但如果数据库中此集合下已经有此_id的话,将插入失败2

save

db.collection_name.save(document)

注:如果不指定_id字段,save方法类似于insert方法。如果指定_id字段,则会更新_id的数据。

db.demo.save({_id:1, age:2})

更新文档

语法

db.collection.update(

,

,

{

upsert: ,

multi: }

)

参数:

query: 查询条件,指定要更新符合哪些条件的文档

update: 更新后的对象或指定一些更新的操作符

$set: 在原基础上累加

upsert: 可选,如果不存在符合条件的记录时是否插入updateObj。默认是false,不插入

multi:可选,mongodb默认只更新找到的第一条记录,如果这个参数为true,就更新所有符合条件的记录。

更新文档

db.demo.insert({name:'zhangsan'})

db.demo.update({name:'zhangsan'},{age:12})

upsert

将students集合的数据中name是lisi的值改为ww,原本数据库中没该数据,也不会插入成功,但是设置upsert为true后就能插入成功

db.demo.update({name:'lisl'}, {name:'ww'}, {upsert:true})

multi

如果有多条age是1的数据,只更新一条,如果想全部更新,需要指定{multi:true}参数

db.school.insert({age:1})

db.school.insert({age:1})

db.school.insert({age:1})

db.school.update({age:1}, {$set:{name:'lisi'}}, {multi:true})

db.school.find()

更新操作符

$set

直接指定更新后的值

use c3;

db.c3.insert({name:'a'});

db.c3.update({name:'a'},{$set:{age:10}});

db.c3.find({})

$inc

在原基础上累加

db.c3.update({name:'a'},{$inc:{age:1}})

$unset

删除指定的键

db.c3.update({name:'2'}, {$unset:{age:11}}) 删除name为'2'的文档中的age为11的数据

$push

向数组中添加元素

db.c3.insert({name:'2', age:10})

db.c3.update({name:'2'}, {$push:{hobbys:'drink'}}, {multi: true})

向name为2的文档中的数组hobbys中添加drink

$ne

$ne类似于MYSQL的not in 或者 not exists

db.c3.update({hobbys:{$ne:"eating"}}, {$push:{"hobbys":"sleeping"}}, {multi:true})

将c3集合中没有hobbys属性,或者hobbys文档中hobbys中没有sleeping的集合中添加hobbys数组或者追加数据到hobbys数组

$addToSet

向集合中添加数组元素(一条)

db.c3.update({name:'a'}, {$addToSet:{"addr":"hb"}})

$each

把数组中的元素逐个添加到集合中(可以添加多条)

db.c3.update({name:'a'}, {$addToSet:{"addr":{$each:["wh", "sh"]}}})

$pop

从数组中移除指定的索引中对应的元素

${pop:{key:1}} 从数组末尾删除一个元素

${pop:{key:-1}} 从数组开头删除一个元素

db.c3.update({name:'a'}, {$pop:{addr:1}})

修改指定索引的元素

修改c3中第一个name为a的集合中add数组文档

db.c3.update({name:'a'}, {$set:{"addr.1":"zh"}})

删除文档

remove方法是用来移除集合中的数据

语法

db.collection.remove(

,

{

justOne:

}

)

参数

-

-

query

(可选)删除的文档的条件。

justOne

(可选)如果设为 true 或 1,则只删除匹配到的多个文档中的第一个

实例

删除wroker集合里name是a的所有文档数据

db.c3.remove({name:'a'})

即时匹配多条也只删除一条

db.c3.remove({name:'a'},{justOne:true})

查询文档

find

db.collection_name.find()

查询指定的列

语法

db.collection_name.find({querywhere},{key:1,key:1})

参数列表

-

-

collection_name

集合的名字

queryWhere

参阅查询条件操作符

key

指定要返回的列

1

表示要显示

实例

只返回显示age列

db.c3.insert([{name:1,age:2},{name:1,age:3},{name:1,age:4}])

db.c3.find({}, {_id:0,age:1})

findOne

查询匹配结果的第一条数据 语法

db.collection_name.findOne()

实例

db.c3.findOne()

$in

查询字段在某个范围内

查询age为3或4的文档中的name和age

db.c3.find({age:{$in:[3,4]}}, {name:1, age:1})

$nin

查询字段不在某个范围内

db.c3.find({age:{$nin:[3,4]}}, {name:1, age:1})

$not

对特定条件取反

db.c3.find({age:{$not:{$gte:3, $lte:4}}})

释:查找age不在3到4之间的

array

where

db.c3.find({$where:"this.age>2"}, {name:1,age:1})

注意:$where后面的条件需要引号

cursor

游标不是 查询结果,而是查询的一个返回资源 或接口,通过这个接口,可以逐条读取数据

var result = db.student.find();

while(result.hasNext()){

printjson(result.next());

}

条件操作符

条件操作符用于比较两个表达式并从mongoDB集合中获取数据

大于、大于等于、小于、小于等于

参数

-

-

$gt

大于

$gte

大于等于

$lt

小于

$lte

小于等于

使用_id进行查询

语法

db.collection_name.find({"_id": ObjectId("value")})

db.c3.find({_id:ObjectId("5d99738a82b8ca8cde36ac7e")})

查询结果集的条数

语法

db.collecton_name.find().count()

db.c3.find().count()

正则匹配

语法

db.collection_name.find({key:/value/})

参数

-

-

collectoin_name

集合名称

key

字段

value

查询name里包含qiao的数据,正则只能匹配字符串

db.c3.insert({name:"qiaogege"})

db.user.find({name:/qiao/})

与和或

and

find方法可以传入多个键(key),每个键(key)以逗号隔开

语法

db.collection_name.find({key1:value1, key2:value2})

查询name是1并且age是2的数据

db.c3.find({name:1,age:2})

or

语法

db.collection_name.find(

{

$or: [

{key1: value1}, {key2:value2}

]

})

查询age=2或者age=3的数据

db.c3.find({$or:[{age:2},{age:3}]})

and和or联用

语法

db.collection_name.find(

{

key1:value1,

key2:value2,

$or: [

{key1: value1},

{key2:value2}

]

}

)

实例

查询age是2并且name是zs或者name是lisi的数据

db.c3.insert([{age:25,name:"zs"},{age:25,name:"lisi"},{age:25,name:"wangwu"}])

db.c3.find({age:25,$or:[{name:"zs"},{name:"lisi"}]})

分页查询

limit

读取指定数量的数据记录 语法

db.collection_name.find().limit(number)

var a = [];

for (var i = 0; i < 10; i++) {

a.push({age:i})

}

db.c3.insert(a);

db.c3.find().limit(3)

skip

跳过指定数量的数据,skip方法同样接收一个数字参数作为跳过记录的条数 语法

db.collection_name.find().skip(number)

db.c3.find().skip(2)

skip+limit实现分页

通常用这种方式来实现分页功能 语法

db.collection_name.find().skip(skipNum).limit(limitNum)

db.c3.find().skip(2).limit(2)

sort排序

sort()方法可以通过参数指定排序的字段,并使用1和-1来指定排序的方式,其中1表示为升序,-1表示降序。语法

db.colleciton_name.find().sort({key:1})

db.collection_name.find().sort({key:-1})

db.c3.find().sort({age:1})

聚合查询

group

group 的作用是按指定的键对集合中的文档进行分组,并执行简单的聚合函数,它与 SQL 中的 SELECT ... GROUP BY 类似。其语法格式如下:

{

group:

{

ns: ,

key: ,

$reduce: ,

$keyf: ,

cond: ,

finalize:

}

}

group 支持的指令及对应描述如下:

指令

类型

描述

ns

string

通过操作执行组的集合,必填。

key

ducoment

要分组的字段或字段,必填。

$reduce

function

在分组操作期间对文档进行聚合操作的函数。 该函数有两个参数:当前文档和该组的聚合结果文档。 必填。 类似having操作

initial

document

初始化聚合结果文档, 必填。

$keyf

function

替代 key。指定用于创建“密钥对象”以用作分组密钥的函数。 使用$keyf而不是 key按计算字段而不是现有文档字段进行分组。

cond

document

用于确定要处理的集合中的哪些文档的选择标准。 如果省略,group 会处理集合中的所有文档。相当于where筛选

finalize

function

在返回结果之前运行,此函数可以修改结果文档。

db.sales.insertMany([

{_id: 1, orderDate: ISODate("2012-07-01T04:00:00Z"), shipDate: ISODate("2012-07-02T09:00:00Z"), attr: {name: "新款椰子鞋", price: 2999, size: 42, color: "香槟金"}},

{_id: 2, orderDate: ISODate("2012-07-03T05:20:00Z"), shipDate: ISODate("2012-07-04T09:00:00Z"), attr: {name: "高邦篮球鞋", price: 1999, size: 43, color: "狮王棕"}},

{_id: 3, orderDate: ISODate("2012-07-03T05:20:10Z"), shipDate: ISODate("2012-07-04T09:00:00Z"), attr: {name: "新款椰子鞋", price: 2999, size: 42, color: "香槟金"}},

{_id: 4, orderDate: ISODate("2012-07-05T15:11:33Z"), shipDate: ISODate("2012-07-06T09:00:00Z"), attr: {name: "极速跑鞋", price: 500, size: 43, color: "西湖蓝"}},

{_id: 5, orderDate: ISODate("2012-07-05T20:22:09Z"), shipDate: ISODate("2012-07-06T09:00:00Z"), attr: {name: "新款椰子鞋", price: 2999, size: 42, color: "香槟金"}},

{_id: 6, orderDate: ISODate("2012-07-05T22:35:20Z"), shipDate: ISODate("2012-07-06T09:00:00Z"), attr: {name: "透气网跑", price: 399, size: 38, color: "玫瑰红"}}

])

假设要将集合 sales 中的文档按照 attr.name 进行分组,并限定参与分组的文档的 shipDate 大于指定时间。对应示例如下:

# select name from sales where shipDate > '2012-07-04T09:00:00Z' group by name

db.runCommand({

group:{

# from操作

ns: 'sales',

# group by操作

key: {"attr.name": 1},

# where操作

cond: {shipDate: {$gt: ISODate('2012-07-04T09:00:00Z')}},

# 这个处理类似having的操作; curr:是当前遍历的文档,result聚合的结果文档

$reduce: function(curr, result){

},

initial: {}

}

})

命令执行后,会返回一个结果档。其中, retval 包含指定字段 attr.name 的数据,count 为参与分组的文档数量,keys 代表组的数量,ok 代表文档状态

# select shipDate, count(price) total from sales where shipDate > '2012-07-04T00:00:00Z' group by shipDate

db.runCommand({

group:{

ns: 'sales',

key: {shipDate: 1},

cond: {shipDate: {$gt: ISODate('2012-07-04T00:00:00Z')}},

initial: {total: 0},

$reduce: function(curr, result){

result.total += curr.attr.price;

}

}

})

# select shipDate, count, total, avg(price) avg from sales where shipDate > '2012-07-04T00:00:00Z' group by shipDate

db.runCommand(

{

group:{

ns: 'sales',

key: {shipDate: 1},

cond: {shipDate: {$gt: ISODate('2012-07-04T00:00:00Z')}},

$reduce: function(curr, result){

result.total += curr.attr.price;

result.count ++;

},

initial: {total: 0, count: 0},

finalize: function(result) {

result.avg = Math.round(result.total / result.count);

}

}

})

上面的示例中改动了 $reduce 函数,目的是为了统计 count。然后新增了 finalize,目的是计算分组中的平均销售额

aggregate聚集框架

管道操作符

常用管道

含义

$group

将collection中的document分组,可用于统计结果

$match

过滤数据,只输出符合结果的文档

$project

修改输入文档的结构(例如重命名,增加、删除字段,创建结算结果等)

$sort

将结果进行排序后输出

$limit

限制管道输出的结果个数

$skip

跳过制定数量的结果,并且返回剩下的结果

$unwind

将数组类型的字段进行拆分

管道的概念:

管道在Unix和Linux中一般用于将当前命令的输出结果作为下一个命令的参数。

MongoDB的聚合管道将MongoDB文档在一个管道处理完毕后将结果传递给下一个管道处理。管道操作是可以重复的。

表达式:处理输入文档并输出。表达式是无状态的,只能用于计算当前聚合管道的文档,不能处理其它的文档。

这里我们介绍一下聚合框架中常用的几个操作:

$project:修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。

$match:用于过滤数据,只输出符合条件的文档。$match使用MongoDB的标准查询操作。

$limit:用来限制MongoDB聚合管道返回的文档数。

$skip:在聚合管道中跳过指定数量的文档,并返回余下的文档。

$unwind:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。

$group:将集合中的文档分组,可用于统计结果。

$sort:将输入文档排序后输出。

$geoNear:输出接近某一地理位置的有序文档。

聚合的表达式 :

表达式

描述

实例

$sum

计算总和。

db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : "$likes"}}}])

$avg

计算平均值

db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$avg : "$likes"}}}])

$min

获取集合中所有文档对应值得最小值。

db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$min : "$likes"}}}])

$max

获取集合中所有文档对应值得最大值。

db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$max : "$likes"}}}])

$push

在结果文档中插入值到一个数组中。

db.mycol.aggregate([{$group : {_id : "$by_user", url : {$push: "$url"}}}])

$addToSet

在结果文档中插入值到一个数组中,但不创建副本。

db.mycol.aggregate([{$group : {_id : "$by_user", url : {$addToSet : "$url"}}}])

$first

根据资源文档的排序获取第一个文档数据。

db.mycol.aggregate([{$group : {_id : "$by_user", first_url : {$first : "$url"}}}])

$last

根据资源文档的排序获取最后一个文档数据

db.mycol.aggregate([{$group : {_id : "$by_user", last_url : {$last : "$url"}}}])

数据准备

use shcool

db.createCollection("student")

var arr = [

{_id:1, name:'zs',subject:'语文',score:90,cid:1},

{_id:2, name:'zs',subject:'数学',score:95,cid:1},

{_id:3, name:'zs',subject:'英语',score:95,cid:1},

{_id:4, name:'ls',subject:'语文',score:80,cid:1},

{_id:5, name:'ls',subject:'数学',score:85,cid:1},

{_id:6, name:'ls',subject:'英语',score:90,cid:1},

{_id:7, name:'ww',subject:'语文',score:70,cid:2},

{_id:8, name:'ww',subject:'数学',score:75,cid:2},

{_id:9, name:'ww',subject:'英语',score:55,cid:2}

]

db.student.save(arr)

db.createCollection("class")

db.class.save([{_id:1, cid: 1, name:"3年1班"}, {_id:2, cid: 2, name:"3年2班"}])

操作

# 查询name为ls的

db.student.aggregate([

{$match: {name:'ls'}}

])

# 查询数学成绩大于等于80,小于90的人

db.student.aggregate([

{$match: {subject : "数学", score: {$gte: 80, $lt: 90}}}

])

# 根据name分组求每个人的选课数

db.student.aggregate([

{$group:{_id: "$name", snumber: {$sum:1}}}

])

#_id: 指定分组的字段

# "$name": 引用集合中的文档"name", 需要用$符号

# snumber是{$sum:1}计算出来的值的别名

# {$sum:1}这里是1, 和mysql中count(1)一个意思

# 求每个人的总分

db.student.aggregate([

{$group:{_id: "$name", snumber: {$sum:"$score"}}}

])

# $sum:"$score" 在这里的意思是sum求和

# 成绩大于等于80的科目求总分,同时总分要大于240分

db.student.aggregate([

{$match: {score: {$gte: 80}}},

{$group:{_id: "$name", snumber: {$sum: "$score"}}},

{$match: {snumber: {$gte:240}}}

])

# $match在group上面前面类似于mysql的where

# $match 在 group后面,类似于mysql的having

# 按名字分组求平均

db.student.aggregate([

{$group:{_id: "$name", snumber: {$avg : "$score"}}}

])

looup

$lookup 的作用是对同一数据库中的集合执行左外连接,其语法格式如下:

{

$lookup:

{

from: ,

localField: ,

foreignField: ,

as:

}

}

领域

描述

from

指定集合名称。

localField

指定输入 $lookup 中的字段。

foreignField

指定from 给定的集合中的文档字段。

as

指定要添加到输入文档的新数组字段的名称。 新数组字段包含from集合中的匹配文档。 如果输入文档中已存在指定的名称,则会覆盖现有字段 。

# select c.*, studentArr from class c inner join student s where c.cid = s.cid

# 不同的是这个studentArr是以数组的形式作为class的字段出现

db.class.aggregate([

{

$lookup: {

from: "student",

localField: "cid", #class中的字段

foreignField: "cid", #student中的字段

as: "studentArr"

}

}

]).pretty()

# 结果部分截取

{

"_id" : 1,

"cid" : 1,

"name" : "3年1班",

"studentArr" : [

{

"_id" : 1,

"name" : "zs",

"subject" : "语文",

"score" : 90,

"cid" : 1

},

{

"_id" : 2,

"name" : "zs",

"subject" : "数学",

"score" : 95,

"cid" : 1

}

}

unwind

unwind 能将包含数组的文档拆分称多个文档,其语法格式如下:

{

$unwind:

{

path: ,

includeArrayIndex: ,

preserveNullAndEmptyArrays:

}

}

指令

类型

描述

path

string

指定数组字段的字段路径, 必填。

includeArrayIndex

string

用于保存元素的数组索引的新字段的名称。

preserveNullAndEmptyArrays

boolean

默认情况下,如果path为 null、缺少该字段或空数组, 则不输出文档。反之,将其设为 true 则会输出文档。

db.shoes.save({_id: 1, brand: "Nick", sizes: [37, 38, 39]})

> db.shoes.aggregate([{$unwind : "$sizes"}])

{ "_id" : 1, "brand" : "Nick", "sizes" : 37 }

{ "_id" : 1, "brand" : "Nick", "sizes" : 38 }

{ "_id" : 1, "brand" : "Nick", "sizes" : 39 }

显然,这样的文档更方便我们做数据处理。preserveNullAndEmptyArrays 指令默认为 false,也就是说文档中指定的 path 为空、null 或缺少该 path 的时候,会忽略掉该文档。假设数据如下:

> db.shoes2.insertMany([

{"_id": 1, "item": "ABC", "sizes": ["S", "M", "L"]},

{"_id": 2, "item": "EFG", "sizes": [ ]},

{"_id": 3, "item": "IJK", "sizes": "M"},

{"_id": 4, "item": "LMN" },

{"_id": 5, "item": "XYZ", "sizes": null}

])

> db.shoes2.aggregate([{$unwind: "$sizes"}])

{ "_id" : 1, "item" : "ABC", "sizes" : "S" }

{ "_id" : 1, "item" : "ABC", "sizes" : "M" }

{ "_id" : 1, "item" : "ABC", "sizes" : "L" }

{ "_id" : 3, "item" : "IJK", "sizes" : "M" }

# 已经忽略了 sizes == null, sizes.leng <= 0, size == undefind的数据

_id 为 2、4 和 5 的文档由于满足 preserveNullAndEmptyArrays 的条件,所以不会被拆分。

以上就是 unwind 的基本用法和作用介绍,更多与 unwind 相关的知识可查阅官方文档 unwind

out

out 的作用是聚合 Pipeline 返回的结果文档,并将其写入指定的集合。要注意的是,out 操作必须出现在 Pipeline 的最后。out 语法格式如下

{ $out: "" }

> db.student.aggregate([

{$group:{_id: "$name", snumber: {$avg : "$score"}}},

{ $out : "avg_result" }

])

> show tables

avg_result

# 发现生成了一个集合 avg_result

Map-Reduce

Map-reduce 用于将大量数据压缩为有用的聚合结果,其语法格式如下:

db.runCommand({

mapReduce: ,

map: ,

reduce: ,

finalize: ,

out: ,

query: ,

sort: ,

limit: ,

scope: ,

jsMode: ,

verbose: ,

bypassDocumentValidation: ,

collation: ,

writeConcern:

})

其中,db.runCommand({mapReduce: }) 也可以写成 db.collection.mapReduce()。各指令的对应描述如下:

指令

类型

描述

mapReduce

collection

集合名称,必填。

map

function

JavaScript 函数,必填。

reduce

function

JavaScript 函数,必填。

out

string or document

指定输出结果,必填。

query

document

查询条件语句。

sort

document

对文档进行排序。

limit

number

指定输入到 map 中的最大文档数量。

finalize

function

修改 reduce 的输出。

scope

document

指定全局变量。

jsMode

boolean

是否在执行map和reduce 函数之间将中间数据转换为 BSON 格式,默认 false。

verbose

boolean

结果中是否包含 timing 信息,默认 false。

bypassDocumentValidation

boolean

是否允许 mapReduce在操作期间绕过文档验证,默认 false。

collation

document

指定要用于操作的排序规则。

writeConcern

document

指定写入级别,不填写则使用默认级别。

简单的 mapReduce

一个简单的 mapReduce 语法示例如下:

var mapFunction = function() { ... };

var reduceFunction = function(key, values) { ... };

db.runCommand(

{

mapReduce: ,

map: mapFunction,

reduce: reduceFunction,

out: { merge: },

query:

})

map 函数负责将每个输入的文档转换为零个或多个文档。map 结构如下:

function() {

...

emit(key, value);

}

emit 函数的作用是分组,它接收两个参数:

key: 指定用于分组的字段

value : 要聚合的字段

在 map 中可以使用 this 关键字引用当前文档。

reduce 结构如下:

function(key, values) {

...

return result;

}

reduce 执行具体的数据处理操作,它接收两个参数:

key:与 map 中的 key 相同,即分组字段。

values:根据分组字段,将相同 key 的值放到同一个数组,values 就是包含这些分类数组的对象。

out 用于指定结果输出,out: 会将结果输出到新的集合,或者使用以下语法将结果输出到已存在的集合中:

out: { :

[, db: ]

[, sharded: ]

[, nonAtomic: ] }

要注意的是,如果 out 指定的 collection 已存在,那么它就会覆盖该集合。在开始学习之前,我们需要准备以下数据:

db.mprds.insertMany([

{_id: 1, numb: 3, score: 9, team: "B"},

{_id: 2, numb: 6, score: 9, team: "A"},

{_id: 3, numb: 24, score: 9, team: "A"},

{_id: 4, numb: 6, score: 8, team: "A"}

])

# emit 指定按numb分组,聚合字段为score

var func_map = function() {

emit(this.team, this.score);

}

var func_reduce = function(key, values) {

return Array.sum(values);

}

# 按numb分组查询 team="A" 每个人的总分

db.student.mapReduce(func_map, func_reduce, {query: {team: "A"}, out: "mprds_result"})

接着定义 map 函数、reduce 函数,并将其应用到集合 mrexample 上。然后为输出结果指定存放位置,这里将输出结果存放在名为 mrexample_result 的集合中。

finallize(having) 剪枝

finallize 用于修改 reduce 的输出结果,其语法格式如下:

function(key, reducedValue) {

...

return modifiedObject;

}

它接收两个参数 :

key,与 map 中的 key 相同,即分组字段。

reduceValue, 一个Ojbect,是reduce的输出

上面我们介绍了 map 和 reduce,并通过一个简单的示例了解 mapReduce 的基本组成和用法。实际上我们还可以编写功能更丰富的 reduce 函数,甚至使用 finallize 修改 reduce 的输出结果。以下 reduce 函数将传入的 values 进行计算和重组,返回一个 reduceVal 对象:

var func_reduce2 = function(key, values){

reduceVal = {team: key, score: values, total: Array.sum(values), count: values.length};

return reduceVal;

};

reduceVal 对象中包含 team、score、total 和 count 四个属性。但我们还想为其添加 avg属性,那么可以在 finallize 函数中执行 avg 值的计算和 avg 属性的添加工作:

var func_finalize = function(key, values){

values.avg = values.total / values.count;

return values;

};

map 保持不变,将这几个函数作用于集合 mprds 上,对应示例如下:

# emit 指定按numb分组,聚合字段为score

var func_map = function() {

emit(this.team, this.score);

}

var func_reduce2 = function(key, values){

reduceVal = {team: key, score: values, total: Array.sum(values), count: values.length};

return reduceVal;

}

# 这个key和上面是同一个(分组的字段), values是func_reduce2函数的返回结果

var func_finalize = function(key, values) {

values.avg = values.total / values.count;

return values;

}

db.mprds.mapReduce(func_map, func_reduce2, {query: {team: "A"}, out: "mprds_result", finalize: func_finalize})

> db.mprds_result.find()

{ "_id" : "A", "value" : { "team" : "A", "score" : [ 9, 9, 8 ], "total" : 26, "count" : 3, "avg" : 8.666666666666666 } }

finallize 在 后面使用,微调 的处理结果。这着看起来像是一个园丁在修剪花圃的枝丫,所以人们将 形象地称为“剪枝”。

要注意的是:map 会将 key 值相同的文档中的 value 归纳到同一个对象中,这个对象会经过 reduce 和 finallize。对于 key 值唯一的那些文档,指定的 key 和 value 会被直接输出。

简单的聚合

count

count 用于计算集合或视图中的文档数,返回一个包含计数结果和状态的文档。其语法格式如下

{

count: ,

query: ,

limit: ,

skip: ,

hint: ,

readConcern:

}

count 支持的指令及对应描述如下:

指令

类型

描述

count

string

要计数的集合或视图的名称,必填。

query

document

查询条件语句。

limit

integer

指定要返回的最大匹配文档数。

skip

integer

指定返回结果之前要跳过的匹配文档数。

hint

string or document

指定要使用的索引,将索引名称指定为字符串或索引规范文档。

假设要统计集合 mprds 中的文档数量,对应示例如下:

db.runCommand({count: 'mprds'})

{ "n" : 4, "ok" : 1 }

假设要统计集合 mprds 中 numb 为 6 的文档数量,对应示例如下:

> db.runCommand({count: 'mprds', query: {numb: {$eq: 6}}})

{ "n" : 2, "ok" : 1 }

指定返回结果之前跳过 1 个文档,对应示例如下:

> db.runCommand({count: 'mprds', query: {numb: {$eq: 6}}, skip: 1})

{ "n" : 1, "ok" : 1 }

更多关于 count 的知识可查阅官方文档 Count。

distinct

distinct 的作用是查找单个集合中指定字段的不同值,其语法格式如下:

{

distinct: "",

key: "",

query: ,

readConcern: ,

collation:

}

指令

类型

描述

distinct

string

集合名称, 必填。

key

string

指定的字段, 必填。

query

document

查询条件语句。

readConcern

document

collation

document

准备以下数据 :

db.createCollection("dress")1

db.dress.insertMany([

{_id: 1, "dept": "A", attr: {"款式": "立领", color: "red" }, sizes: ["S", "M" ]},

{_id: 2, "dept": "A", attr: {"款式": "圆领", color: "blue" }, sizes: ["M", "L" ]},

{_id: 3, "dept": "B", attr: {"款式": "圆领", color: "blue" }, sizes: "S" },

{_id: 4, "dept": "A", attr: {"款式": "V领", color: "black" }, sizes: ["S" ] }

])

# 计集合 dress 中所有文档的 dept 字段的不同值

# select distinct dept from dress

db.runCommand ( { distinct: "dress", key: "dept" } )

{ "values" : [ "A", "B" ], "ok" : 1 }

# select distinct attr.款式 from dress

db.runCommand ( { distinct: "dress", key: "attr.款式" } )

{ "values" : [ "立领", "圆领", "V领" ], "ok" : 1 }

#就算值是数组, distinct 也能作出正确处理

db.runCommand ( { distinct: "dress", key: "sizes" } )

{ "values" : [ "M", "S", "L" ], "ok" : 1 }

参考

mongodb objetcid_mongodb(1)相关推荐

  1. windows安装MongoDB环境以及在pycharm中配置可视化插件

    安装MongoDB数据库 参考这里 安装PyMongo python3 -m pip3 install pymongo指定版本 python3 -m pip3 install pymongo==3.5 ...

  2. SQL与NoSQL的区别 以MySQL与MongoDB为例

    异同对比 1.语言和结构层面 SQL数据库,是基于表的,并且用结构化语言也就是SQL来定义和操纵数据.一方面,这是非常强大的:SQL是最通用和最广泛使用的选项之一,使其成为一个安全的选择,尤其适用于复 ...

  3. php配置mongodb扩展、安装mongodb服务教程

    安装mongodb服务. 1.下载mongodb: mongodb 提供了可用于 32 位和 64 位系统的,你可以从mongodb官网下载安装. mongodb下载地址:https://www.mo ...

  4. MongoDB之conf配置文件详解

    详细看一下mongodb配置文件. mongodb.conf # mongodb.conf# 数据库文件位置 dbpath=/var/lib/mongodb#日志文件的路径 logpath=/var/ ...

  5. CentOS7.4 安装mongodb

    温馨提示:我的环境是腾讯云自带的CentOS7.4 x64 镜像,本地环境是win10 x64 专业版,ssh工具是用的win10 自带的cmd, 远程工具版本是Robo 3T 1.2.1 . 如果环 ...

  6. Centos7下安装MongoDB

    简介 MongoDB 是一个基于分布式 文件存储的NoSQL数据库 由C++语言编写,运行稳定,性能高 旨在为 WEB 应用提供可扩展的高性能数据存储解决方案 查看官方网站 MongoDB特点 模式自 ...

  7. php mongodb execute,php简单操作mongodb

    您现在的位置是:网站首页>>PHP>>php php简单操作mongodb 发布时间:2019-09-29 16:34:25作者:wangjian浏览量:525点赞量:0 一: ...

  8. 【MongoDB异常】Exception authenticating MongoCredential解决方法

    我们通过ideal编辑器编辑 springboot时候,出现这个错误: com.mongodb.MongoSecurityException: Exception authenticating Mon ...

  9. mongodb插入数据获取本次插入的mongodb id

    最近接了一个别人的项目做二次开发,使用php进行mongodb的数据操作时,需要插入数据后得到相应的mongodb 中的id,简单代码如下 $data = array('test' => 'aa ...

最新文章

  1. 3dmax Vray建筑可视化入门学习教程
  2. Applet相关知识
  3. 使用 Xbrowser4远程连接到 CentOS 7
  4. VS2013上利用InstallShield2013LimitedEdition/C#生成安装包
  5. python环境管理命令_conda管理Python环境
  6. 线性拟合polyfit_6.数据分析(1) 描述性统计量和线性回归(2)
  7. 自然语言系列学习之表示学习与知识获取(七)利用关系路径进行关系抽取
  8. java B锁_Java中15种锁的介绍
  9. POE交换机隐藏指标是什么?
  10. 论ACM ICPC_Ruins He
  11. 复习---使用基础语法实现栈及迭代
  12. mysql 主从复制 表结构_MySQL主从复制-双主结构
  13. struts的action属性自动注入原理
  14. matlab中edge函数,matlabedge函数用法
  15. 同步Chrome浏览器插件
  16. Docker一探究竟
  17. 逻辑或、与、非、或非、与非、异或、同或运算
  18. SmartGit功能介绍
  19. 耐人思考的“30秒法则”
  20. java语言基础知识(完整版)

热门文章

  1. SpringBoot:Spring boot 主程序的功能SpringApplication.run(启动流程)
  2. elastic search与postgresql的数据同步
  3. Java优雅的记录日志:log4j实战篇
  4. 反射(二) :整型数组能存字附---反射”暴力“超越数据类型的检测
  5. pearson特征选择matlab,使用sklearn做特征选择
  6. Mybatis判断表是否存在
  7. Jenkins+GitLab+Docker+SpringCloud+Kubernetes实现可持续自动化微服务
  8. Spring之ApplicationContextAware接口详解
  9. Git之同一台电脑连接多个远程仓库
  10. CODE[VS]1012 最大公约数和最小公倍数问题