MongoDB 基础知识学习笔记

时间:2021-06-28 22:58:30

注意:本文假设您已经安装好 MongoDB 数据库并启动它了。

连接 MongoDB、数据库操作、集合操作

  • 连接 MongoDB

mongo ip:port/dbName -u username -p password

例如:mongo 127.0.0.1:27017/test -u test -p test

  • 连接 MongoDB

mongo

use dbName

db.auth("username", "password")

  • 查看当前数据库版本

db.version()

  • 查看当前数据库状态

db.stats()

  • 查看所有数据库

show dbs

  • 查看所有集合

show tables



show collections

  • 查看当前所在数据库

db

  • 使用数据库

use dbName

  • 删除当前正在使用的数据库

db.dropDatabase()

  • 创建集合

db.createCollection("collectionName")

  • 删除集合

db.collectionName.drop()

MongoDB 备份、恢复数据库

  • 导出

mongodump -h ip:port -d dbName -u username -p password -o dumpDir

-h:MongDB 所在服务器地址(如:127.0.0.1),也可以指定端口号(如:127.0.0.1:27017)

-d:需要备份的数据库实例(如:test)

-o:备份的数据存放位置(如:D:\data\dump),该目录需提前建立,备份完成后会在 D:\data\dump 目录下建立一个 test 目录用于存放该数据库实例的备份数据。

  • 导入

mongorestore -h ip:port -d dbName dumpDir

--host ip:port、-h ip:port:MongoDB所在服务器地址(默认是 localhost:27017)

--db、-d:需要恢复的数据库实例,例如:test,当然这个名称也可以和备份时候的不一样,比如test2

--drop:恢复时先删除当前数据,然后恢复备份的数据。即:恢复后,备份操作之后添加、修改的数据都会被删除!

dumpDir:mongorestore 最后的一个参数,设置备份数据所在位置(如:D:\data\dump\test)。注意:不能同时指定 dumpDir 和 --dir 选项。

--dir:指定备份的目录。注意:不能同时指定 dumpDir 和 --dir 选项。

MongoDB 插入文档

MongoDB 使用 insert() 或 save() 方法向集合中插入文档,语法如下:

db.collectionName.insert(document)

例如:

db.mycol.insert({

title : 'MongoDB 教程',

description : 'MongoDB 是一个 Nosql 数据库',

by : 'php中文网',

website : 'http://www.php.cn',

tags : ['mongodb', 'database', 'NoSQL'],

likes : 100

});

也可以将数据定义为一个变量:

document=({

title : 'MongoDB 教程',

description : 'MongoDB 是一个 Nosql 数据库',

by : 'php中文网',

website : 'http://www.php.cn',

tags : ['mongodb', 'database', 'NoSQL'],

likes : 100

});

再执行插入操作:

db.mycol.insert(document)

注意:插入文档也可以使用 db.collectionName.save(document) 命令。如果不指定 _id 字段,save() 方法类似于 insert() 方法;如果指定 _id 字段,则会更新该 _id 的数据。

db.mycol.save({

_id : ObjectId("5ede4968cfd2ea1834cc87c7"),

title : 'MongoDB 教程(修改)',

description : 'MongoDB 是一个 Nosql 数据库(修改)',

by : 'php中文网(修改)',

website : 'http://www.php.cn',

tags : ['mongodb(修改)', 'database(修改)', 'NoSQL(修改)'],

likes : 100

});

MongoDB 3.2 版本后还有以下几种语法可用于插入文档:

db.collectionName.insertOne(document):向指定集合中插入一个文档

db.collectionName.insertMany(document):向指定集合中插入多个文档

例1:插入一个文档

var document = db.mycol.insertOne({"a": 3})

例2:插入多个文档

var res = db.mycol.insertMany([{"b": 3}, {'c': 4}])

例3:一次插入多条数据(先创建数组,再将文档放在数组中):

var arr = [];

for(var i=1 ; i<=20000 ; i++){

arr.push({"num" : i});

}

db.mycol.insert(arr);

MongoDB 更新文档

MongoDB 使用 update() 和 save() 方法来更新集合中的文档。接下来让我们详细来看下两个函数的应用及其区别。

1、update() 方法用于更新已存在的文档。语法格式如下:

db.collectionName.update(

,

,

{

upsert : ,

multi : ,

writeConcern :

}

)

参数说明:

  • query:查询条件,类似于关系型数据库查询语句中的 where 条件。
  • update:更新的操作符或对象,类似于关系型数据库修改语句中的 set。
  • upsert:可选参数。当不存在符合 query 查询条件的记录时是否插入,true 为插入,默认是 false。
  • multi:可选参数。是否更新符合 query 查询条件的所有记录。参数为 true 时则就把按条件查出来的多条记录全部更新。默认是 false,即只更新找到的第一条记录。
  • writeConcern:可选参数,指定抛出异常的级别。有以下几种异常级别。

    WriteConcern.NONE:没有异常抛出。

    WriteConcern.NORMAL:仅抛出网络错误异常,没有服务器错误异常。

    WriteConcern.SAFE:抛出网络错误异常、服务器错误异常;并等待服务器完成写操作。

    WriteConcern.MAJORITY:抛出网络错误异常、服务器错误异常;并等待一个主服务器完成写操作。

    WriteConcern.FSYNC_SAFE:抛出网络错误异常、服务器错误异常;写操作等待服务器将数据刷新到磁盘。

    WriteConcern.JOURNAL_SAFE:抛出网络错误异常、服务器错误异常;写操作等待服务器提交到磁盘的日志文件。

    WriteConcern.REPLICAS_SAFE:抛出网络错误异常、服务器错误异常;等待至少2台服务器完成写操作。

例如:通过 update() 方法来更新标题(title)

db.mycol.update({'title' : 'MongoDB 教程'}, {$set : {'title' : 'MongoDB'}})

以上语句只会修改第一条发现的文档,如果要修改多个文档,则需要设置 multi 参数为 true,如下:

db.mycol.update({'title' : 'MongoDB 教程'}, {$set : {'title' : 'MongoDB'}}, {multi : true})

2、save() 方法通过传入的文档来替换已有文档。语法格式如下:

db.collectionName.save(

,

{

writeConcern:

}

)

参数说明:

  • document:文档数据。
  • writeConcern:可选参数,指定抛出异常的级别。

下例替换 _id 为 56064f89ade2f21f36b03136 的文档数据:

db.mycol.save({

"_id" : ObjectId("56064f89ade2f21f36b03136"),

"title" : "MongoDB",

"description" : "MongoDB 是一个 Nosql 数据库",

"by" : "php",

"website" : "http://www.php.cn",

"tags" : ["mongodb", "NoSQL"],

"likes" : 110

})

**3、使用的 $set 或 \(unset 操作符来新增或移除集合中的键值对**
\)set 或 $unset 操作符的语法格式如下:

db.collectionName.update(, {\(set: {<field1>: "", ...}})
db.collectionName.update(<query>, {\)unset: {: "", ...}})

例如:

db.mycol.update({"_id" : "56064f89ade2f21f36b03136"}, {\(set : {"status" : "ON"}})
db.mycol.update({"_id" : "56064f89ade2f21f36b03136"}, {\)unset : {"status" : "OFF"}})

注:如果指定的字段不存在则操作不做任何处理。

**4、Mongodb 字段更新 \(setOnInsert 操作符**
如果 update 的更新参数 upsert 为 true(即:如果要更新的文档不存在则插入一条新记录),若要更新的文档不存在,\)setOnInsert 操作符会将指定的值赋给指定的字段,若要更新的文档存在,$setOnInsert 操作符不做任何处理。

db.mycol.update({"title" : 'MongoDB 教程'}, {$setOnInsert : {'title' : 'MongoDB'}}, {upsert : true})

5、MongoDB 更新案例

  • 只更新第一条记录:

db.mycol.update({"count" : {\(gt : 5}}, {\)set : {"status" : "OK"}});

  • 全部更新:

db.mycol.update({"count" : {\(gt : 5}}, {\)set : {"status" : "OK"}}, false, true);

  • 只添加第一条:

db.mycol.update({"count" : {\(gt : 5}}, {\)set : {"status" : "OK"}}, true, false);

  • 全部添加:

db.mycol.update({"count" : {\(gt : 5}}, {\)set : {"status" : "OK"}}, true, true);

  • 全部更新:

db.mycol.update({"count" : {\(gt : 5}}, {\)inc : {"count" : 1}}, false, true);

  • 只更新第一条记录:

db.mycol.update({"count" : {\(gt : 5}}, {\)inc : {"count" : 1}}, false, false);

MongoDB 3.2 版本后还有以下几种语法可用于插入文档:

db.collectionName.updateOne(document):更新指定集合中的单个文档

db.collectionName.updateMany(document):更新指定集合中的多个文档

例1:更新单个文档

db.mycol.updateOne({"title" : "abc"}, {$set : {"likes" : "100"}})

例2、更新多个文档

db.mycol.updateMany({"likes" : {\(gt : "10"}}, {\)set : {"title" : "xyz"}})

MongoDB 删除文档

remove() 方法的基本语法格式如下:

db.collectionName.remove(

,



)

如果 MongoDB 是 2.6 版本以后的,语法格式如下:

db.collectionName.remove(

,

{

justOne: ,

writeConcern:

}

)

参数说明:

  • query:可选参数。删除的文档的条件。
  • justOne:可选参数。如果设为 true 或 1,则只删除一个文档。默认值是 false。
  • writeConcern:可选参数。指定抛出异常的级别。

remove() 方法 并不会真正释放空间,需要继续执行 db.repairDatabase() 来回收磁盘空间。

db.repairDatabase() 或 db.runCommand({ repairDatabase: 1 })

remove() 方法已经过时了,现在官方推荐使用 deleteOne() 和 deleteMany() 方法。

  • 移除 title 为 'MongoDB 教程' 的文档:

db.mycol.remove({'title':'MongoDB 教程'})

  • 如果只想删除第一条找到的记录可以设置 justOne 为 true 或 1:

db.collectionName.remove(DELETION_CRITERIA, 1)

  • 如果想删除所有数据,可以使用以下方式(类似于关系型数据库中的 truncate 命令):

db.mycol.remove({})

  • 如删除集合中的全部文档:

db.mycol.deleteMany({})

  • 删除 status 等于 ON 的全部文档:

db.mycol.deleteMany({"status" : "ON"})

  • 删除 status 等于 ON 的一个文档:

db.mycol.deleteOne({"status" : "D"})

MongoDB 查询文档

MongoDB 查询文档使用 find() 方法,该方法以非结构化的方式来显示所有文档。

MongoDB 查询数据的语法格式如下:

db.collectionName.find(query, projection)

还可以使用 pretty() 方法以易读的方式来读取数据,语法格式如下:

db.collectionName.find(query, projection).pretty()

参数说明:

  • query:可选参数。使用查询操作符指定的查询条件。
  • projection:可选参数。使用投影操作符指定返回的键。查询时若需返回文档中所有键值,则省略该参数即可(默认省略)。projection 的入参格式为{"columnA" : 0/1, "columnB" : 0/1},其中 columnA、columnB 表示要查询的集合中的字段,0/1 表示取或不取。

注:若不指定 projection,则默认返回所有键;指定 projection 时有两种模式,如下:

db.collectionName.find(query, {"title" : 1, "by" : 1}) // inclusion模式 指定返回的键,不返回其他键

db.collectionName.find(query, {"title" : 0, "by" : 0}) // exclusion模式 指定不返回的键,返回其他键

_id 键默认返回,需要主动指定 _id:0 才会隐藏。两种模式不可混用(因为这样的话无法推断其他键是否应返回)。如下:

db.collection.find(query, {"title" : 1, "by" : 0}) // 错误

只能 全1 或 全0,除了在 inclusion 模式时可以指定 _id:0

db.collection.find(query, {"_id" : 0, "title" : 1, "by" : 1}) // 正确

除 find() 方法外,还有一个 findOne() 方法,它只返回一个文档。

示例:

  • 查询集合中的所有文档

db.mycol.find().pretty();

  • 查询集合中的所有文档,只显示 _id 和 title 列

db.mycol.find().pretty({}, {'title' : 1});

  • 查询集合中的所有文档,只显示 title 列

db.mycol.find().pretty({}, {'_id' : 0, 'title' : 1});

MongoDB 条件语句查询:

  • 等于:{ : }

    如:db.mycol.find({"title" : "MongoDB 教程"}).pretty(),相当于 RDBMS 中的 where by = 'MongoDB 教程'
  • 不等于:{ : {\(ne : <value>}}
    如:db.mycol.find({"likes" : {\)ne : 50}}).pretty(),相当于 RDBMS 中的 where likes != 50
  • 小于:{ : {\(lt : <value>}}
    如:db.mycol.find({"likes" : {\)lt : 50}}).pretty(),相当于 RDBMS 中的 where likes < 50
  • 小于等于:{ : {\(lte : <value>}}
    如:db.mycol.find({"likes" : {\)lte : 50}}).pretty(),相当于 RDBMS 中的 where likes <= 50
  • 大于:{ : {\(gt : <value>}}
    如:db.mycol.find({"likes" : {\)gt : 50}}).pretty(),相当于 RDBMS 中的 where likes > 50
  • 大于等于:{ : {\(gte : <value>}}
    如:db.mycol.find({"likes" : {\)gte : 50}}).pretty(),相当于 RDBMS 中的 where likes >= 50

MongoDB 中的 AND 条件:find() 方法可以传入多个键(key),多个键(key)之间用逗号隔开,即常规 SQL 的 AND 条件。

语法格式如下:

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

下例通过 by 和 title 来查询 MongoDB 中 MongoDB 教程的文档:

db.mycol.find({"by" : "MongoDB", "title" : "MongoDB 教程"}).pretty()

以上实例类似于 RDBMS 中的 WHERE 语句:WHERE by='菜鸟教程' AND title='MongoDB 教程'

MongoDB 中的 OR 条件:该类型的条件语句需要使用关键字 $or,语法格式如下:

db.collectionName.find({$or : [{key1 : value1}, {key2 : value2}]}).pretty()

下例查询键 by 的值为 MongoDB 或键 title 的值为 MongoDB 教程的文档:

db.mycol.find({$or : [{"by" : "MongoDB"}, {"title" : "MongoDB 教程"}]}).pretty()

MongoDB 中 AND 和 OR 联合使用,下例中 AND 和 OR 联合使用:

db.mycol.find({"likes" : {$gt : 50}, $or: [{"by" : "MongoDB"}, {"title" : "MongoDB 教程"}]}).pretty()

类似于 RDBMS 中的 WHERE 语句:WHERE likes > 50 AND (by = 'MongoDB' OR title = 'MongoDB 教程')

MongoDB 条件操作符

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

  • 大于(>):$gt
  • 大于等于(>=):$gte
  • 小于(<):$lt
  • 小于等于(<=):$lte

MongoDB 大于(>)操作符:$gt

获取 mycol 集合中 likes 大于 100 的数据:

db.mycol.find({"likes" : {$gt : 100}}).pretty(),类似于 SQL 语句:Select * from mycol where likes > 100;

MongoDB 大于等于(>=)操作符:$gte

获取 mycol 集合中 likes 大于等于 100 的数据:

db.mycol.find({"likes" : {$gte : 100}}).pretty(),类似于 SQL 语句:Select * from mycol where likes >= 100;

MongoDB 小于(<)操作符:$lt

获取 mycol 集合中 likes 小于 150 的数据:

db.mycol.find({"likes" : {$lt : 150}}).pretty(),类似于SQL语句:Select * from mycol where likes < 150;

MongoDB 小于等于(<=)操作符:$lte

获取 mycol 集合中 likes 小于等于 150 的数据:

db.mycol.find({"likes" : {$lte : 150}}).pretty(),类似于SQL语句:Select * from mycol where likes <= 150;

MongoDB 使用小于(<)和大于(>)查询:\(lt、\)gt

获取 mycol 集合中 likes 大于 100 小于 200 的数据:

db.mycol.find({"likes" : {$lt :200, $gt : 100}}).pretty(),类似于SQL语句:Select * from mycol where likes > 100 AND likes < 200;

MongoDB 模糊查询

  • 查询 title 包含"教"字的文档:

db.mycol.find({"title" : /教/}).pretty()

  • 查询 title 字段以"教"字开头的文档:

db.mycol.find({"title" : /^教/}).pretty()

  • 查询 titl e字段以"教"字结尾的文档:

db.mycol.find({"title" : /教$/}).pretty()

MongoDB 条件操作符 $type

$type 操作符是基于 BSON 类型来检索集合中匹配的数据类型,并返回结果。MongoDB 中可以使用的类型如下所示:

  • Double —— 1
  • String —— 2
  • Object —— 3
  • Array —— 4
  • Binary data —— 5
  • Undefined —— 6(已废弃)
  • Object id —— 7
  • Boolean —— 8
  • Date —— 9
  • Null —— 10
  • Regular Expression —— 11
  • JavaScript —— 13
  • Symbol —— 14
  • JavaScript (with scope) —— 15
  • 32-bit integer —— 16
  • Timestamp —— 17
  • 64-bit integer —— 18
  • Min key —— 255(Query with -1)
  • Max key —— 127

$type 操作符示例

获取 mycol 集合中 title 为 String 的数据:

db.mycol.find({"title" : {\(type : 2}}) 或 db.mycol.find({"title" : {\)type : 'string'}})

MongoDB limit() 方法

如果要在 MongoDB 中读取指定数量的文档,可以使用 MongoDB 的 limit() 方法,limit() 方法接受一个数字参数,该参数指定要从 MongoDB 中读取的文档个数。limit() 方法语法格式如下:

db.collectionName.find().limit(number)

下例查询文档中的2条记录:

db.mycol.find({}, {"title" : 1, "_id" : 0}).limit(2)

注:如果没有指定 limit() 方法中的参数,则显示集合中的所有文档。

MongoDB Skip() 方法

除了可以使用 limit() 方法来读取指定数量的文档外,还可以用 skip() 方法来跳过指定数量的文档,skip()

方法也接受一个数字参数作为跳过的文档个数。skip() 方法语法格式如下:

db.collectionName.find().limit(number).skip(number)

下例只会显示第二条文档数据:

db.mycol.find({}, {"title" : 1, "_id" : 0}).limit(1).skip(1)

注:skip() 方法默认参数为0。

MongoDB 排序

在 MongoDB 中使用 sort() 方法对文档排序,该方法可以通过参数指定排序的字段,并使用 1(升序) 和 -1(降序) 来指定排序的方式。sort() 方法语法格式如下:

db.collectionName.find().sort({KEY : 1})

下例将 mycol 集合中的文档按字段 likes 的降序排列:

db.mycol.find({}, {"title" : 1, "_id" : 0}).sort({"likes" : -1})

注:skip()、limilt()、sort() 三个一起执行时,执行的先后顺序是 sort()、skip()、limit()。

MongoDB 索引

索引通常能够极大的提高查询效率,如果没有索引,MongoDB 在读取数据时就会扫描集合中的所有文档并选择那些符合查询条件的记录。这种扫描全集合的查询效率是非常低的,特别在处理大量数据时,查询可能要花费几十秒甚至几分钟,这对网站的性能是非常致命的。索引是特殊的数据结构,索引存储在一个易于遍历读取的数据集合中,索引是对数据库表中一列或多列的值进行排序的一种结构。MongoDB 中创建索引的语法格式如下:

db.collectionName.ensureIndex(keys, options) // 3.0.0 版本前

db.collectionName.createIndex(keys, options) // 3.0.0 版本后

Keys 为要创建的索引字段,1 指按升序创建索引,-1 指按降序创建索引。例如:

db.mycol.createIndex({"title" : 1})

也可以设置多个字段创建索引(即:RDBMS 中的复合索引)

db.mycol.createIndex({"title" : 1, "description" : -1})

options 为可选参数,可取值为:

  • background:Boolean 类型,默认值为 false。创建索引的过程会阻塞其它数据库操作,background 可指定以后台方式创建索引。
  • unique:Boolean 类型,默认值为 false。建立的索引是否唯一。
  • name:String 类型。指定索引的名称。如果未指定,MongoDB 通过连接索引的字段名和排序顺序生成一个索引名称。
  • dropDups:Boolean 类型,默认值为 false。3.0+ 版本已废弃。在建立唯一索引时是否删除重复记录。
  • sparse:Boolean 类型,默认值为 false。对文档中不存在的字段数据不启用索引。如果设置为 true,则在索引字段中不会查询出不包含对应字段的文档。
  • expireAfterSeconds:Integer类型。指定集合的生存时间,单位为秒。
  • v:索引的版本号。默认的索引版本取决于 MongoDB 创建索引时运行的版本。
  • weights:索引权重值,数值在 1 到 99,999 之间,表示该索引相对于其他索引字段的得分权重。
  • default_language:String 类型,默认为英语。对于文本索引,该参数决定了停用词及词干和词器的规则的列表。
  • language_override:String 类型,默认值为 language。对于文本索引,该参数指定了包含在文档中的字段名,语言覆盖默认的 language。

在创建索引时加 background:true 选项,让创建工作在后台执行:

db.mycol.createIndex({"title" : 1, "likes" : 1}, {background : true})

索引相关操作

  • 查看集合索引

db.collectionName.getIndexes()

  • 查看集合索引大小

db.collectionName.totalIndexSize()

  • 删除集合所有索引

db.collectionName.dropIndexes()

  • 删除集合指定索引

db.collectionName.dropIndex("索引名称")

利用 TTL 对存储的数据进行失效时间设置:经过指定的时间段后或在指定的时间点过期,MongoDB 独立线程去清除数据。类似于设置定时自动删除任务,可以清除历史记录或日志等前提条件,设置 Index 的关键字段为日期类型 new Date()。

例、数据记录中 createDate 为日期类型,设置在创建记录 180 秒后删除。:

db.mycol.createIndex({"createDate" : 1}, {expireAfterSeconds : 180})

例、由记录中设定日期点清除。如设置某记录在2020年6月13日12点左右删除,则该记录中需添加 "ClearUpDate": new Date('Jun 13, 2020 12:00:00'),且 Index中expireAfterSeconds 的值设置为 0。

db.mycol.createIndex({"ClearUpDate" : 1}, {expireAfterSeconds : 0})

MongoDB 设置 TTL 时注意事项

  • 索引关键字段必须是 Date 类型。
  • 删除操作是非立即执行的。MongoDB 中扫描集合过期数据并删除是独立线程执行,默认 60s 扫描一次,删除也不一定是立即删除成功。
  • 单字段索引,混合索引不支持。

MongoDB 聚合

MongoDB 中的聚合(aggregate)主要用于处理数据(如:统计平均值、求和等),并返回计算后的结果。类似 sql 语句中的 count(*)。MongoDB 中聚合的方法使用 aggregate(),其语法格式如下:

db.collectionName.aggregate(AGGREGATE_OPERATION)

例、统计每个作者所写的文章数:

db.mycol.aggregate([{\(group : {"_id" : "\)by", "num" : {$sum : 1}}}])

类似于:select by as _id, count(*) as num from mycol group by by

一些常用聚合表达式

  • $sum:计算总和。

db.mycol.aggregate([{\(group : {"_id" : "\)by", "num" : {\(sum : "\)likes"}}}])

  • $avg:计算平均值。

db.mycol.aggregate([{\(group : {"_id" : "\)by", "num" : {\(avg : "\)likes"}}}])

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

db.mycol.aggregate([{\(group : {"_id" : "\)by", "num" : {\(min : "\)likes"}}}])

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

db.mycol.aggregate([{\(group : {"_id" : "\)by", "num" : {\(max : "\)likes"}}}])

  • $push:在结果文档中插入值到一个数组中。

db.mycol.aggregate([{\(group : {"_id" : "\)by", "website" : {\(push: "\)website"}}}])

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

db.mycol.aggregate([{\(group : {"_id" : "\)by", "website" : {\(addToSet : "\)website"}}}])

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

db.mycol.aggregate([{\(group : {"_id" : "\)by", "first_website" : {\(first : "\)website"}}}])

  • $last:根据资源文档的排序获取最后一个文档数据。

db.mycol.aggregate([{\(group : {"_id" : "\)by", "last_website" : {\(last : "\)website"}}}])

MongoDB 管道

管道在 Unix 和 Linux 中一般用于将当前命令的输出结果作为下一个命令的参数。MongoDB 的聚合管道将 MongoDB 文档在一个管道处理完毕后将结果传递给下一个管道处理。管道操作是可以重复的。

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

常用的几个管道操作

  • $project:修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。
  • \(match:用于过滤数据,只输出符合条件的文档。\)match 使用 MongoDB 的标准查询操作。
  • $limit:用来限制 MongoDB 聚合管道返回的文档数。
  • $skip:在聚合管道中跳过指定数量的文档,并返回余下的文档。
  • $unwind:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。
  • $group:将集合中的文档分组,可用于统计结果。
  • $sort:将输入文档排序后输出。
  • $geoNear:输出接近某一地理位置的有序文档。

管道操作符实例

  • $project 实例

db.mycol.aggregate({$project : {"title" : 1, "description" : 1}})

上例结果中就只有 _id、tilte、description 三个字段了(默认包含 _id 字段),如果不想要 _id 字段则可以这样写:

db.mycol.aggregate({$project : {"_id" : 0, "title" : 1, "description" : 1}})

  • $match 实例

db.mycol.aggregate([

{\(match : {"likes" : {\)gt : 10, \(lte : 100}}},
{\)group : {"_id": null, "count": {$sum: 1}}}

]);

$match 用于获取 likes 大于10且小于等于100的记录,然后将符合条件的记录送到 $group 管道操作符进行处理。注意:当 $match 和 $group 同时存在时,顺序会影响检索结果,如下:

db.mycol.aggregate([

{\(match : {"likes" : {\)gt : 10, \(lte : 100}}},
{\)group : {"_id": null, "count": {\(sum: 1}}}
]);
db.mycol.aggregate([
{\)group : {"_id": null, "count": {\(sum: 1}}},
{\)match : {"likes" : {$gt : 10, $lte : 100}}}

]);

  • $skip 实例

db.mycol.aggregate({$skip : 2});

经过 $skip 管道操作符处理后,前2个文档就被"过滤"掉了。

** 按日、按月、按年、按周、按小时、按分钟等聚合操作**

db.mycol.aggregate([

{\(match : {"by" : "runoob", pubDate : {\)gt : new Date(2020, 2, 2)}}},

{\(group : {"_id" : {\)dayOfMonth : '\(pubDate'}, "page_view" : {\)sum : 1}}},

{$sort : {"_id" : 1}}

])

时间关键字如下:

  • $dayOfYear: 返回该日期是这一年的第几天(全年 366 天)。
  • $dayOfMonth: 返回该日期是这一个月的第几天(1~31)。
  • $dayOfWeek: 返回的是这个周的星期几(1~7:1-星期日、7-星期六)。
  • $year: 返回该日期的年份部分。
  • $month: 返回该日期的月份部分(1~12)。
  • $week: 返回该日期是所在年的第几个星期(0~53)。
  • $hour: 返回该日期的小时部分。
  • $minute: 返回该日期的分钟部分。
  • $second: 返回该日期的秒部分(以0~59之间的数字形式返回日期的第二部分,但可以是60来计算闰秒)。
  • $millisecond:返回该日期的毫秒部分(0~999)。
  • $dateToString: 格式化日期时间成字符串。如:

db.mycol.aggregate([

{\(project : {
"pubDate": {\)dateToString : {format: "%Y-%m-%d %H:%M:%S", date: "$pubDate"}},

"by" : true

}

}

])

本文参考

1、菜鸟教程:https://www.runoob.com/mongodb/mongodb-tutorial.html

2、MongoDB手册:https://www.runoob.com/mongodb/mongodb-tutorial.html

3、其他相关书籍或博文等