MongoDB 相关概念
MongoDB 中基本的概念是文档、集合、数据库。
数据库
MongoDB 的单个实例可以容纳多个独立的数据库,每一个都有自己的集合和权限,不同的数据库也放置在不同的文件中。
文档
文档类似于 MySQL 中的一条记录(row),其大小不能超过 16M。文档内的属性不能包含 null 字符,句点(.),美元符号($),不能以 system 开头。
文档的存储是以 JSON 的形式保存,在 MongoDB 中以 BSON(二进制的 JSON)的形式存储着。
{"site":"www.bestguo.top", "name":"BestGuo 的小窝"}
集合
集合中保存着一组文档,类似于 MySQL 中的表。集合存在于数据库中,没有固定的表结构。存储的方式可以如下。
{"site":"www.bestguo.top", "name":"BestGuo 的小窝"}
{"site":"www.bestguo.top", "name":"BestGuo 的小窝", "create": "2019-01-01" }
{"site":"www.bestguo.top", "name":"BestGuo 的小窝", "views": "6672", "clients": "2835"}
SQL 与 NoSQL 对比
SQL 与 NoSQL 的概念对比如下,这样就更好的理解 MongoDB 了。
SQL术语/概念 | MongoDB术语/概念 | 解释/说明 |
---|---|---|
database | database | 数据库 |
table | collection | 数据库表/集合 |
row | document | 数据记录行/文档 |
column | field | 数据字段/域 |
index | index | 索引 |
table joins | 表连接,MongoDB 不支持 | |
primary key | primary key | 主键,MongoDB 自动将 _id 字段设置为主键 |
MongoDB 数据库操作
show 命令
使用 show 命令查看全部的数据库
show databases
show dbs
# ============= Run Results ============= #
admin 0.000GB
config 0.000GB
local 0.000GB
test 0.001GB
使用 show 命令显示集合
show collections
# ============= Run Results ============= #
a
item
mythings
students
user
use 命令
使用 use 命令切换数据库
use admin # 切换至 admin 数据库
use test # 切换至 test 数据库
db 命令
使用 db 命令查看正在使用的数据库
db
# ============= Run Results ============= #
test
创建集合/数据库
这些操作在 BestGuo 数据库中
MongoDB 中没有直接创建数据库的命令,但是使用 use 命令之后,并且执行添加集合的操作,数据库才算是真正意义上的创建。
使用 db.createCollection() 方法来创建集合。
db.createCollection("user")
或者从一个不存在的集合中插入一个文档时,它也会自动创建该集合。插入文档的操作将在后面介绍。
db.user_2_0.insert({"name": "bestguo2020", "age": 18})
/*********** Run Results ***********/
WriteResult({ "nInserted" : 1 })
删除集合
使用 db.collectionName.drop() 来删除集合,其中 collectionName 指的是集合名字。
db.user.drop()
插入文档
插入文档可以使用 db.collectionName.save() 方法和 db.collectionName.insert() 方法插入数据。
在插入整数时,由于 json 格式只有 number 类型,mongodb 为了保证不出错将 shell 中所有的 int、double 类型都存为 double。当然官方也考虑到用户实际想保存整型的问题,故允许在 json 中增加整型函数 NumberInt() 。
var data = []; for(var i = 1; i < 11; i++) { data.push({ "name": "德川" + i, "age": NumberInt(17 + i), "gender": "男", "phone": "0592-114514" }) } db.user_2_0.insertMany(data)
insert 方法
插入一条数据
db.user_2_0.save(
{
"name": "田所浩二",
"age": 24,
"gender": "男",
"phone": "0592-114514"
}
)
插入多条数据,由于 MongoDB 的 shell 界面是 JavaScript,因此可以编写 JavaScript 的代码。
var data = [];
for(var i = 0; i < 1000; i++) {
data.push({
"name": "德川" + i,
"age": 42 + i,
"gender": "男",
"phone": "0592-114514"
})
}
db.user_2_0.insert(data)
/***** Run Results *****/
1000
Inserted 1 record(s) in 15ms
save 方法
db.user_2_0.save(
{
"name": "lisi",
"age": 21,
"gender": "男",
"phone": "1145141919811"
}
)
两个方法的区别:若指定的 id 存在时,save 方法会将原有的文档进行替换,不存在则和 insert 方法是一样的。
使用 save 方法
第一次插入的数据
db.user_2_0.save(
{
"_id": "114514",
"name": "我修院",
"age": 24,
"gender": "男",
"phone": "0592-114514"
}
)
第二次插入的数据时,会有如下的提示信息。
db.user_2_0.save(
{
"_id": "114514",
"name": "德川",
"age": 24,
"gender": "男",
"phone": "0592-114514"
}
)
/***** Run Results *****/
Updated 1 existing record(s) in 2ms
使用 insert 方法
再次插入数据时,会出现 duplicate key error collection 的错误信息。
db.user_2_0.insert(
{
"_id": "114514",
"name": "德川",
"age": 24,
"gender": "男",
"phone": "0592-114514"
}
)
/***** Run Results *****/
E11000 duplicate key error collection: BestGuo.user_2_0 index: _id_ dup key: { _id: "114514" }
更新文档
使用 db.collectionName.update() 方法对文档进行更新。使用 $set 来修改原有文档的内容
db.user_2_0.update(
// 修改的条件
{
"_id": "114514"
},
// 修改的内容
{
$set: {
"name": "德川我修院"
}
}
)
/***** Run Results *****/
Updated 1 existing record(s) in 1ms
在使用 $set 更新时,如果文档中不存在这个属性则会将不存在的属性添加进来。
db.user_2_0.update(
{
"_id": "114514"
},
{
$set: {
"name": "德川我修院",
"vip": true
}
}
)
/***** Run Results *****/
Updated 1 existing record(s) in 1ms
{
"_id" : "114514",
"name" : "德川我修院",
"age" : 24.0,
"gender" : "男",
"phone" : "0592-114514",
"vip" : true
}
查询文档
使用 db.collectionName.find() 方法来查询出文档数据。未限制条件时则查询出全部的数据。
> db.user_2_0.find()
{ "_id" : ObjectId("62b97a2e305de3247a4e89cc"), "name" : "bestguo2020", "age" : 18 }
{ "_id" : ObjectId("62b97eace2bf2e431a87d8f6"), "name" : "zhangsan", "age" : 18, "gender" : "男", "phone" : "1145141919810" }
{ "_id" : ObjectId("62b97f23e2bf2e431a87d8f7"), "name" : "lisi", "age" : 21, "gender" : "男", "phone" : "1145141919811" }
{ "_id" : ObjectId("62b97fd4e2bf2e431a87d8f8"), "name" : "田所浩二", "age" : 24, "gender" : "男", "phone" : "0592-114514" }
{ "_id" : "114514", "name" : "德川我修院", "age" : 24, "gender" : "男", "phone" : "0592-114514", "vip" : true }
{ "_id" : ObjectId("62b984cfe2bf2e431a87d8f9"), "name" : "德川0", "age" : 42, "gender" : "男", "phone" : "0592-114514" }
{ "_id" : ObjectId("62b984cfe2bf2e431a87d8fa"), "name" : "德川1", "age" : 43, "gender" : "男", "phone" : "0592-114514" }
Type "it" for more
使用 findOne() 方法查询出一条数据
> db.user_2_0.findOne()
{
"_id" : ObjectId("62b97a2e305de3247a4e89cc"),
"name" : "bestguo2020",
"age" : 18
}
调用 pretty() 方法将文档以格式化之后展示出来。
> db.user_2_0.find().pretty()
{
"_id" : ObjectId("62b97a2e305de3247a4e89cc"),
"name" : "bestguo2020",
"age" : 18
}
{
"_id" : ObjectId("62b97eace2bf2e431a87d8f6"),
"name" : "zhangsan",
"age" : 18,
"gender" : "男",
"phone" : "1145141919810"
}
Type "it" for more
显示指定的字段
若要指定显示某些字段,可以在第二个参数中指定出想要的字段,不指定时则全部显示。若指定的字段不存在,则不显示。
db.user_2_0.find(
{}, # 查询的条件
{ # 需要显示的字段
name: 1,
age: 1,
asd: 1 # 这个字段不存在,就不显示
}
)
AND 条件
AND 条件很简单,只需在 find 方法中传入 JSON 格式即可。比如我找一个 name 为”田所浩二“,age 为”24“的人。可以写成{name: "田所浩二", age: 24}
。下面的语句可以理解成 where name = '田所浩二' and age = 24
。第一层的{}
所代表的就是 AND了。
> db.user_2_0.find(
... {
... name: "田所浩二",
... age: 24
... }
... )
# ============= Run Results ============= #
{ "_id" : ObjectId("62b97fd4e2bf2e431a87d8f8"), "name" : "田所浩二", "age" : 24, "gender" : "男", "phone" : "0592-114514" }
OR 条件
OR 条件需要使用 $or 来设置。下面的例子展示了查询姓名为”田所浩二“或者”德川我修院“的人。可以理解为where name = '田所浩二' or name = '德川我修院'
,
db.user_2_0.find(
{
$or: [
{
name: "田所浩二"
},
{
name: "德川我修院"
}
]
}
)
操作符
MongoDB中条件操作符有:
- (>) 大于(great than) - $gt
- (<) 小于 (less than)- $lt
- (>=) 大于等于(great than or equals)- $gte
- (<= ) 小于等于(less than or equals)- $lte
great than
大于操作符 $gt,比如我要查询出大于 100 岁的人。
> db.user_2_0.find({
... age: {
... $gt: 100
... }
... })
# ============= Run Results ============= #
{ "_id" : ObjectId("62b984cfe2bf2e431a87d934"), "name" : "德川59", "age" : 101,
"gender" : "男", "phone" : "0592-114514" }
{ "_id" : ObjectId("62b984cfe2bf2e431a87d935"), "name" : "德川60", "age" : 102,
"gender" : "男", "phone" : "0592-114514" }
{ "_id" : ObjectId("62b984cfe2bf2e431a87d936"), "name" : "德川61", "age" : 103,
"gender" : "男", "phone" : "0592-114514" }
{ "_id" : ObjectId("62b984cfe2bf2e431a87d937"), "name" : "德川62", "age" : 104,
"gender" : "男", "phone" : "0592-114514" }
Type "it" for more
less than
小于操作符 $lt,查询出大于 30 小于 50 岁的人。
> db.user_2_0.find({
age: {
$gt: 30,
$lt: 50
}
})
# ============= Run Results ============= #
{ "_id" : ObjectId("62b984cfe2bf2e431a87d8f9"), "name" : "德川0", "age" : 42, "gender" : "男", "phone" : "0592-114514" }
{ "_id" : ObjectId("62b984cfe2bf2e431a87d8fa"), "name" : "德川1", "age" : 43, "gender" : "男", "phone" : "0592-114514" }
{ "_id" : ObjectId("62b984cfe2bf2e431a87d8fb"), "name" : "德川2", "age" : 44, "gender" : "男", "phone" : "0592-114514" }
{ "_id" : ObjectId("62b984cfe2bf2e431a87d8fc"), "name" : "德川3", "age" : 45, "gender" : "男", "phone" : "0592-114514" }
{ "_id" : ObjectId("62b984cfe2bf2e431a87d8fd"), "name" : "德川4", "age" : 46, "gender" : "男", "phone" : "0592-114514" }
Type "it" for more
great than or equals
大于等于操作符 $gte,比如我要查询出大于等于 200 岁,小于 210 岁的人。、
> db.user_2_0.find({
age: {
$gte: 200,
$lt: 210
}
})
# ============= Run Results ============= #
{ "_id" : ObjectId("62b984cfe2bf2e431a87d997"), "name" : "德川158", "age" : 200, "gender" : "男", "phone" : "0592-114514" }
{ "_id" : ObjectId("62b984cfe2bf2e431a87d998"), "name" : "德川159", "age" : 201, "gender" : "男", "phone" : "0592-114514" }
{ "_id" : ObjectId("62b984cfe2bf2e431a87d999"), "name" : "德川160", "age" : 202, "gender" : "男", "phone" : "0592-114514" }
{ "_id" : ObjectId("62b984cfe2bf2e431a87d99a"), "name" : "德川161", "age" : 203, "gender" : "男", "phone" : "0592-114514" }
{ "_id" : ObjectId("62b984cfe2bf2e431a87d99b"), "name" : "德川162", "age" : 204, "gender" : "男", "phone" : "0592-114514" }
{ "_id" : ObjectId("62b984cfe2bf2e431a87d99c"), "name" : "德川163", "age" : 205, "gender" : "男", "phone" : "0592-114514" }
Type "it" for more
less than or equals
小于等于操作符 $gte,比如我要查询出大于 200 岁,小于等于 205 岁的人。
> db.user_2_0.find({
age: {
$gt: 200,
$lte: 205
}
})
# ============= Run Results ============= #
{ "_id" : ObjectId("62b984cfe2bf2e431a87d998"), "name" : "德川159", "age" : 201, "gender" : "男", "phone" : "0592-114514" }
{ "_id" : ObjectId("62b984cfe2bf2e431a87d999"), "name" : "德川160", "age" : 202, "gender" : "男", "phone" : "0592-114514" }
{ "_id" : ObjectId("62b984cfe2bf2e431a87d99a"), "name" : "德川161", "age" : 203, "gender" : "男", "phone" : "0592-114514" }
{ "_id" : ObjectId("62b984cfe2bf2e431a87d99b"), "name" : "德川162", "age" : 204, "gender" : "男", "phone" : "0592-114514" }
{ "_id" : ObjectId("62b984cfe2bf2e431a87d99c"), "name" : "德川163", "age" : 205, "gender" : "男", "phone" : "0592-114514" }
模糊查询
在 MongoDB 中没有专门的模糊查询关键字,但是可以使用正则的方式来实现模糊查询。
> db.user_2_0.find({
... age: {
... $gte: 200,
... $lt: 205
... },
... name: /田所/
... })
# ============= Run Results ============= #
{ "_id" : ObjectId("62b985d9e2bf2e431a87dd7f"), "name" : "田所浩二158", "age" : 200, "gender" : "男", "phone" : "0592-114514" }
{ "_id" : ObjectId("62b985d9e2bf2e431a87dd80"), "name" : "田所浩二159", "age" : 201, "gender" : "男", "phone" : "0592-114514" }
{ "_id" : ObjectId("62b985d9e2bf2e431a87dd81"), "name" : "田所浩二160", "age" : 202, "gender" : "男", "phone" : "0592-114514" }
{ "_id" : ObjectId("62b985d9e2bf2e431a87dd82"), "name" : "田所浩二161", "age" : 203, "gender" : "男", "phone" : "0592-114514" }
{ "_id" : ObjectId("62b985d9e2bf2e431a87dd83"), "name" : "田所浩二162", "age" : 204, "gender" : "男", "phone" : "0592-114514" }
{ "_id" : ObjectId("62b985f6e2bf2e431a87e167"), "name" : "田所浩二158", "age" : 200, "gender" : "男", "phone" : "0592-114514" }
{ "_id" : ObjectId("62b985f6e2bf2e431a87e168"), "name" : "田所浩二159", "age" : 201, "gender" : "男", "phone" : "0592-114514" }
{ "_id" : ObjectId("62b985f6e2bf2e431a87e169"), "name" : "田所浩二160", "age" : 202, "gender" : "男", "phone" : "0592-114514" }
{ "_id" : ObjectId("62b985f6e2bf2e431a87e16a"), "name" : "田所浩二161", "age" : 203, "gender" : "男", "phone" : "0592-114514" }
{ "_id" : ObjectId("62b985f6e2bf2e431a87e16b"), "name" : "田所浩二162", "age" : 204, "gender" : "男", "phone" : "0592-114514" }
联动
查询出名字为”田所浩二x“(x表示数字,比如田所浩二114、田所浩二115)这一类的姓名,且年龄 18 ~ 24 岁(不含 24 岁含 18 岁)或在 114 ~ 119 (都包含) 之间。
> db.user_2_0.find({
... name: /田所浩二\d+$/,
... $or: [
... {
... age: {
... $gt: 18,
... $lte: 24
... }
... },
... {
... age: {
... $gte: 114,
... $lte: 119
... }
... },
... ]
... })
# ============= Run Results ============= #
{ "_id" : ObjectId("62b985d9e2bf2e431a87dd29"), "name" : "田所浩二72", "age" : 114, "gender" : "男", "phone" : "0592-114514" }
{ "_id" : ObjectId("62b985d9e2bf2e431a87dd2a"), "name" : "田所浩二73", "age" : 115, "gender" : "男", "phone" : "0592-114514" }
{ "_id" : ObjectId("62b985d9e2bf2e431a87dd2b"), "name" : "田所浩二74", "age" : 116, "gender" : "男", "phone" : "0592-114514" }
{ "_id" : ObjectId("62b985d9e2bf2e431a87dd2c"), "name" : "田所浩二75", "age" : 117, "gender" : "男", "phone" : "0592-114514" }
{ "_id" : ObjectId("62b985d9e2bf2e431a87dd2d"), "name" : "田所浩二76", "age" : 118, "gender" : "男", "phone" : "0592-114514" }
{ "_id" : ObjectId("62b985d9e2bf2e431a87dd2e"), "name" : "田所浩二77", "age" : 119, "gender" : "男", "phone" : "0592-114514" }
{ "_id" : ObjectId("62baa3dae2bf2e431a87e4ba"), "name" : "田所浩二19", "age" : 19, "gender" : "男", "phone" : "0592-114514" }
{ "_id" : ObjectId("62baa3dae2bf2e431a87e4bb"), "name" : "田所浩二20", "age" : 20, "gender" : "男", "phone" : "0592-114514" }
{ "_id" : ObjectId("62baa3dae2bf2e431a87e4bc"), "name" : "田所浩二21", "age" : 21, "gender" : "男", "phone" : "0592-114514" }
{ "_id" : ObjectId("62baa3dae2bf2e431a87e4bd"), "name" : "田所浩二22", "age" : 22, "gender" : "男", "phone" : "0592-114514" }
{ "_id" : ObjectId("62baa3dae2bf2e431a87e4be"), "name" : "田所浩二23", "age" : 23, "gender" : "男", "phone" : "0592-114514" }
{ "_id" : ObjectId("62baa3dae2bf2e431a87e4bf"), "name" : "田所浩二24", "age" : 24, "gender" : "男", "phone" : "0592-114514" }
删除文档
删除文档可以使用 remove 方法、deleteOne 方法和 deleteMany 方法。
使用 remove 删除一条文档,需要传入一个参数 {justOne: 1}
,若不传递或者设置成 0,则会删除集合中的全部文档。
> db.user_2_0.remove({}, {justOne: 1})
# ============= Run Results ============= #
WriteResult({ "nRemoved" : 1 })
使用 deleteOne 能达到删除一条数据的效果。remove 传入参数 {justOne: 1}
和 deleteOne 删除一条信息的规则是第一条数据。
> db.user_2_0.deleteOne({})
# ============= Run Results ============= #
{ "acknowledged" : true, "deletedCount" : 1 }
也可以按照条件删除元素,比如删除 114 ~ 514 岁(都包含)的人,使用 deleteOne 。
> db.user_2_0.deleteMany({
age: {
$gte: 114,
$lte: 514,
}
})
# ============= Run Results ============= #
{
"acknowledged" : true,
"deletedCount" : 1211.0
}
排序
排序使用 sort() 方法,该方法作用于查询之后。比如我要查询姓名为”田所浩二x“(x表示数字,比如田所浩二114、田所浩二115)这一类的姓名,且按年龄升序排序。使用 1 和 -1 来指定排序的方式,其中 1 为升序排列,而 -1 是用于降序排列。
> db.user_2_0.find({name: /田所浩二\d+$/}).sort({age: 1}).pretty();
# ============= Run Results ============= #
{
"_id" : ObjectId("62baa3dae2bf2e431a87e4b9"),
"name" : "田所浩二18",
"age" : 18,
"gender" : "男",
"phone" : "0592-114514"
}
{
"_id" : ObjectId("62baa3dae2bf2e431a87e4ba"),
"name" : "田所浩二19",
"age" : 19,
"gender" : "男",
"phone" : "0592-114514"
}
{
"_id" : ObjectId("62baa3dae2bf2e431a87e4bb"),
"name" : "田所浩二20",
"age" : 20,
"gender" : "男",
"phone" : "0592-114514"
}
{
"_id" : ObjectId("62baa3dae2bf2e431a87e4bc"),
"name" : "田所浩二21",
"age" : 21,
"gender" : "男",
"phone" : "0592-114514"
}
{
"_id" : ObjectId("62baa3dae2bf2e431a87e4bd"),
"name" : "田所浩二22",
"age" : 22,
"gender" : "男",
"phone" : "0592-114514"
}
Type "it" for more
Limit 与 Skip
limit() 方法就是从查询的结果中取出前几条文档,skip() 方法就是从查询的结果中跳过几个文档,从第几个文档开始查询。
使用 limit 查询前 5 条数据。
> db.user_2_0.find({}).limit(5)
# ============= Run Results ============= #
{ "_id" : ObjectId("62babe68dc0663b7a70c6daf"), "name" : "德川1", "age" : 18, "gender" : "男", "phone" : "0592-114514" }
{ "_id" : ObjectId("62babe68dc0663b7a70c6db0"), "name" : "德川2", "age" : 19, "gender" : "男", "phone" : "0592-114514" }
{ "_id" : ObjectId("62babe68dc0663b7a70c6db1"), "name" : "德川3", "age" : 20, "gender" : "男", "phone" : "0592-114514" }
{ "_id" : ObjectId("62babe68dc0663b7a70c6db2"), "name" : "德川4", "age" : 21, "gender" : "男", "phone" : "0592-114514" }
{ "_id" : ObjectId("62babe68dc0663b7a70c6db3"), "name" : "德川5", "age" : 22, "gender" : "男", "phone" : "0592-114514" }
使用 skip,跳过前两条数据,从第三条数据开始查询。
> db.user_2_0.find({}).skip(2)
# ============= Run Results ============= #
{ "_id" : ObjectId("62babe68dc0663b7a70c6db1"), "name" : "德川3", "age" : 20, "g
ender" : "男", "phone" : "0592-114514" }
{ "_id" : ObjectId("62babe68dc0663b7a70c6db2"), "name" : "德川4", "age" : 21, "g
ender" : "男", "phone" : "0592-114514" }
{ "_id" : ObjectId("62babe68dc0663b7a70c6db3"), "name" : "德川5", "age" : 22, "g
ender" : "男", "phone" : "0592-114514" }
{ "_id" : ObjectId("62babe68dc0663b7a70c6db4"), "name" : "德川6", "age" : 23, "g
ender" : "男", "phone" : "0592-114514" }
{ "_id" : ObjectId("62babe68dc0663b7a70c6db5"), "name" : "德川7", "age" : 24, "g
ender" : "男", "phone" : "0592-114514" }
{ "_id" : ObjectId("62babe68dc0663b7a70c6db6"), "name" : "德川8", "age" : 25, "g
ender" : "男", "phone" : "0592-114514" }
{ "_id" : ObjectId("62babe68dc0663b7a70c6db7"), "name" : "德川9", "age" : 26, "g
ender" : "男", "phone" : "0592-114514" }
{ "_id" : ObjectId("62babe68dc0663b7a70c6db8"), "name" : "德川10", "age" : 27, "
gender" : "男", "phone" : "0592-114514" }
limit 和 skip 方法联动可实现分页的功能,每一页有 4 条数据。要显示出 4 条数据 limit 一定是 4,每一页的话,就应该是 4 的倍数。
db.user_2_0.find({}).skip(0).limit(4)
db.user_2_0.find({}).skip(4).limit(4)
db.user_2_0.find({}).skip(8).limit(4)
#......
db.user_2_0.find({}).skip(4n).limit(4)
聚合
MongoDB 中聚合(aggregate)主要用于处理数据(诸如统计平均值,求和等),并返回计算后的数据结果。和关系型数据库 MySQL 类似。MySQL 有很多聚合函数,在 MongoDB 中采用的方式是以 $函数名
的形式来表示的。
利用分组统计个数
在指定使用哪个字段分组时,记得要加上”$“
接下来使用 aggregate 来统计集合中”男“、”女“性别个数。
> db.user_2_0.aggregate(
{
# $group 指的是将查询结果进行分组
$group: {
_id: "$gender", # 使用文档中的哪个字段进行分组
gender_count: {
$sum: NumberInt(1) # 使用 $sum 进行求和
}
}
}
)
# ============= Run Results ============= #
{ "_id" : "女", "gender_count" : 6 }
{ "_id" : "男", "gender_count" : 10 }
为什么统计的时候,要写个 1 在这里?
gender_count: {
$sum: NumberInt(1) # 使用 $sum 进行求和
}
若写成 0 或者 2 的时候,那么得出的结果是什么样的呢?
# ============= $sum: 2 ============= #
{ "_id" : "女", "gender_count" : 12 }
{ "_id" : "男", "gender_count" : 20 }
# ============= $sum: 0 ============= #
{ "_id" : "女", "gender_count" : 0 }
{ "_id" : "男", "gender_count" : 0 }
看到上面的结果,就明白了,这个设置 $sum: 1
的意义在于分组之后,性别”男“中有几个 1 ,性别”女“中有几个 1,但是这里出现了 10 个性别为”男“,所以 1 * 10 = 10
。通过设置 $sum: 1
可以统计个数。设置 $sum: 2
也就不难理解了。
上面的写法,在 SQL 语句中可以理解成
select gender, count(*) from user_2_0 group by gender
利用分组求平均值、最小值和最大值
平均值使用 $avg,最小值和最大值分别为 $min 和 $max 。获取男女中的平均年龄、最大值和最小值。
db.user_2_0.aggregate([
{
$group: { # group 里面存着的是分组之后的字段
_id: "$gender",
# 最大年龄
max_age: {
$max: "$age"
},
# 最小年龄
min_age: {
$min: "$age"
},
# 平均年龄
avg_age: {
$avg: "$age"
}
}
}
])
# ============= Run Results ============= #
{ "_id" : "男", "max_age" : 27, "min_age" : 18, "avg_age" : 22.5 }
{ "_id" : "女", "max_age" : 23, "min_age" : 18, "avg_age" : 20.5 }
分组结果排序
若要对分组结果进行排序,不能直接调用 sort 方法,而是需要在聚合方法中加一个 $sort 即可,然后去指定分组之后的字段
db.user_2_0.aggregate([
{
$group: {
_id: "$gender",
max_age: {
$max: "$age"
},
min_age: {
$min: "$age"
},
avg_age: {
$avg: "$age"
}
}
},
{
$sort: { # 排序
avg_age: 1 # 指定分组之后的哪个字段进行排序
}
}
])
# ============= Run Results ============= #
{ "_id" : "女", "max_age" : 23, "min_age" : 18, "avg_age" : 20.5 }
{ "_id" : "男", "max_age" : 27, "min_age" : 18, "avg_age" : 22.5 }
请勿发布违反中国大陆地区法律的言论,请勿人身攻击、谩骂、侮辱和煽动式的语言。