48个MongoDB的命令和查询,供开发人员和数据库管理员(DBA)使用

这篇文章讲述了开发人员和数据库管理员在日常开发和运维中经常使用的MongoDB查询和命令。

快速介绍

在这个智能技术的新时代,数据以大量产生,每一条数据对于不断发展的行业都同等重要。用户产生的数据包括结构化、半结构化和非结构化数据。结构化数据是将数据存储在表和行中,而非结构化数据包括图像、视频和语音剪辑。由于结构化和非结构化数据的数据量不断增加,NoSQL Database的必要性就出现了。

它为开发人员提供了设计模式和可扩展的数据库平台的便利,为数据库管理员提供了一个安全且高效的平台。

MongoDB是什么?

MongoDB是一款面向文档、跨平台、开源的NoSQL数据库,用于存储半结构化数据,它是用C++编写的。MongoDB不像传统的关系型数据库使用表和行来存储数据,而是使用键值对来存储数据。为了方便开发人员和管理员学习和使用,下面是一些常用的MongoDB命令。

让我们开始吧。

基本命令

1. 版本检查

首先要检查MongoDB服务器和Mongo Shell安装的版本。在Linux终端或Windows的CMD命令提示符上运行以下命令。

mongod --version

C:WindowsSystem32>mongod --version
db version v4.2.7
git version: 51d9fe12b5d19720e72dcd7db0f2f17dd9a19212
allocator: tcmalloc
modules: none
build environment:
    distmod: 2012plus
    distarch: x86_64
    target_arch: x86_64

我们也可以使用mongod命令来检查版本,如下所示。

mongo –version

C:WindowsSystem32>mongo --version
MongoDB shell version v4.2.7
git version: 51d9fe12b5d19720e72dcd7db0f2f17dd9a19212
allocator: tcmalloc
modules: none
build environment:
    distmod: 2012plus
    distarch: x86_64
    target_arch: x86_64

2. 列出MongoDB命令

该命令将帮助用户找出在MongoDB中可以使用的所有命令。在Mongo Shell上运行该命令。

help()

mongo> db.help()
DB方法:
db.adminCommand(nameOrDocument) – 切换到“admin”数据库,并运行命令[只是调用db.runCommand(…)] db.aggregate([pipeline], {options}) – 在此数据库上执行无集合聚合; 返回一个游标
db.auth(username, password)
db.cloneDatabase(fromhost) – 仅在MongoDB 4.0及以下版本上有效
db.commandHelp(name) 返回命令的帮助
db.copyDatabase(fromdb, todb, fromhost) – 仅在MongoDB 4.0及以下版本上有效
db.createCollection(name, {size: …, capped: …, max: …})
db.createUser(userDocument)
db.createView(name, viewOn, [{$operator: {…}}, …], {viewOptions})
db.currentOp() 显示数据库中当前正在执行的操作
db.dropDatabase(writeConcern)
db.dropUser(username)
db.eval() – 已弃用
db.fsyncLock() 将数据刷新到磁盘并锁定服务器以进行备份
db.fsyncUnlock() 在db.fsyncLock()后解锁服务器
db.getCollection(cname) 与db [‘cname']或db.cname相同
db.getCollectionInfos([filter]) – 返回包含数据库集合名称和选项的列表
db.getCollectionNames()
db.getLastError() – 仅返回错误消息字符串
db.getLastErrorObj() – 返回完整的状态对象
db.getLogComponents()
db.getMongo() 获取服务器连接对象
db.getMongo().setSlaveOk() 允许在复制从服务器上查询
db.getName()
db.getProfilingLevel() – 已弃用
db.getProfilingStatus() – 返回是否开启了分析以及慢阈值
db.getReplicationInfo()
db.getSiblingDB(name) 获取与此数据库相同服务器上的数据库
db.getWriteConcern() – 返回用于此数据库上任何操作的写关注,如果设置,则从服务器对象继承
db.hostInfo() 获取有关服务器主机的详细信息
db.isMaster() 检查副本主要状态
db.killOp(opid) 终止数据库中的当前操作
db.listCommands() 列出所有数据库命令
db.loadServerScripts() 加载db.system.js中的所有脚本
db.logout()
db.printCollectionStats()
db.printReplicationInfo()
db.printShardingStatus()
db.printSlaveReplicationInfo()
db.resetError()
db.runCommand(cmdObj) 运行数据库命令。 如果cmdObj是一个字符串,则将其变为{cmdObj: 1}
db.serverStatus()
db.setLogLevel(level,)
db.setProfilingLevel(level,slowms) 0=off 1=slow 2=all
db.setVerboseShell(flag) 在shell输出中显示额外信息
db.setWriteConcern() – 设置写关注以用于对数据库的写入
db.shutdownServer()
db.stats()
db.unsetWriteConcern() – 取消对数据库写入的写关注
db.version() 当前服务器版本
db.watch() – 打开一个更改流游标以报告其非系统集合的所有更改。

3. 数据库统计信息

以下命令将提供数据库的详细信息,包括多个集合和相关参数。

db.stats()

> db.stats()
{
        "db" : "test",
        "collections" : 0,
        "views" : 0,
        "objects" : 0,
        "avgObjSize" : 0,
        "dataSize" : 0,
        "storageSize" : 0,
        "numExtents" : 0,
        "indexes" : 0,
        "indexSize" : 0,
        "scaleFactor" : 1,
        "fileSize" : 0,
        "fsUsedSize" : 0,
        "fsTotalSize" : 0,
        "ok" : 1
}

4. 创建新的数据库或切换到现有的数据库

此简单命令可用于创建新数据库(如果不存在)或切换到现有数据库。在MongoDB中,“test”是默认数据库,因此用户在登录Mongo Shell后使用“test”数据库。

use DB_Name

mongos> use geekFlareDB
切换到数据库geekFlareDB

5. 列出所有数据库

这个命令用于列出所有的数据库。

show dbs

mongo> show dbs
admin        0.000GB
config       0.002GB
geekFlareDB  0.000GB
test         0.000GB

6. 检查当前正在使用的数据库

在Mongo Shell上运行以下命令,以查看当前正在使用的数据库。

db

> db
GeekFlare

 7. 删除数据库

此命令用于删除所需的数据库。在MongoDB客户端上运行此命令。请确保在运行删除命令之前选择数据库。否则,它将删除默认的“test”数据库。

db.dropDatabase()

首先列出所有的数据库,切换到其中一个,然后删除它

> show dbs
admin     0.000GB
config    0.001GB
local     0.000GB
test      0.000GB
training  0.000GB
>
> use training
切换到数据库training
>
> db.dropDatabase()
{ "dropped" : "training", "ok" : 1 }

8. 创建集合

集合类似于关系型数据库中的表。

创建集合命令包含两个参数。集合由零个或多个文档组成。因此,对于创建集合,必须使用命令中的名称作为必需参数,另外可能包括文档的名称、大小和索引。

  • 创建一个简单的集合。

语法db.createCollection(Name,Options)

示例

> use geekFlare
切换到数据库geekFlare
>
> db.createCollection("geekFlareCollection")
{ "ok" : 1 }
>
> show collections
geekFlareCollection
  • 创建一个固定大小的集合

通过限制集合中要插入的文档的大小和数量来创建固定大小的集合。固定大小的集合具有删除最老的文档以为新文档腾出空间的属性。

语法

db.createCollection(Name,{capped : true, size : sizeLimit , max : documentLimit })

示例:让我们创建一个固定大小的集合,插入一条记录并获取它

> db.createCollection("Login",{capped:true,max:1,size:200})
{ "ok" : 1 }
>
> db.Login.insertMany([{"id":1,status:"Active"},{"id":2,status:"Hold"},{"id":3,status:"Pending"}])
{
        "acknowledged" : true,
        "insertedIds" : [
                ObjectId("5edc5f4f411247725e75e52e"),
                ObjectId("5edc5f4f411247725e75e52f"),
                ObjectId("5edc5f4f411247725e75e530")
        ]
}
>
> db.Login.find()
{ "_id" : ObjectId("5edc5f4f411247725e75e530"), "id" : 3, "status" : "Pending" }

9. 删除集合

删除集合的命令类似于关系型数据库中的DDL。它在执行命令期间对所需集合进行锁定。删除集合将从数据库中删除集合以及与该集合相关的所有索引。要删除集合,需要使用drop()方法。

成功删除时返回true,如果发生任何错误或数据库不存在,则返回false。

语法collectionName.drop()

示例

> use geekFlare
切换到数据库geekFlare
>
> show collections
geekFlareCollection
>
> db.geekFlareCollection.drop()
true
>
> db.geekFlareCollection.drop()
false

与CRUD操作相关

10. 将文档插入集合

在MongoDB中,文档类似于RDBMS中的元组。

要创建文档,使用insert()方法。insert()方法在现有集合中创建一个或多个文档。如果数据库中不存在集合,它还会创建集合。在MongoDB中,文档是无模式的,这意味着可以插入任意数量的键。

  • 插入单个记录

要插入一条记录,可以使用insert()insertOne()方法。

语法: collectionName.insertOne({document})

示例:

> db.geekFlareCollection.insertOne( {
 code: "P123", Qty: 200, status: "Active"
});
{
        "acknowledged" : true,
        "insertedId" : ObjectId("5ed309725429283aee2e134d")
}
  • 插入多个记录

要插入多个记录,需要将记录列表传递给insert()insertMany()方法。

语法:

collectionName.insertMany([{document1},{document2},{ document3}….{ documentn}])

示例:

db.geekFlareCollection.insertMany([
... { code: "P1", Qty: 100, status: "Active"},
... { code: "P2", Qty: 200, status: "Active"},
... { code: "P3", Qty: 0, status: "Dective"}
... ]);
{
        "acknowledged" : true,
        "insertedIds" : [
                ObjectId("5edf7b4e18b2c26b9dfe8cac"),
                ObjectId("5edf7b4e18b2c26b9dfe8cad"),
                ObjectId("5edf7b4e18b2c26b9dfe8cae")
        ]
}
> db.geekFlareCollection.find()
{ "_id" : ObjectId("5edf546fdfa12b33b7cb75b8"), "product" : "bottles", "Qty" : 100 }
{ "_id" : ObjectId("5edf546fdfa12b33b7cb75b9"), "product" : "bread", "Qty" : 20 }
{ "_id" : ObjectId("5edf546fdfa12b33b7cb75ba"), "product" : "yogurt", "Qty" : 30 }
{ "_id" : ObjectId("5edf7b4e18b2c26b9dfe8cac"), "code" : "P1", "Qty" : 100, "status" : "Active" }
{ "_id" : ObjectId("5edf7b4e18b2c26b9dfe8cad"), "code" : "P2", "Qty" : 200, "status" : "Active" }
{ "_id" : ObjectId("5edf7b4e18b2c26b9dfe8cae"), "code" : "P3", "Qty" : 0, "status" : "Dective" }
>
  • 批量插入记录

可以通过执行initializeOrderedBulkOp() initializeUnorderedBulkOp()方法以有序和无序的方式插入大量文档。

语法:

var bulk = db.collectionName.initializeUnorderedBulkOp();

bulk.insert({document1} );

bulk.insert({document2} );

bulk.insert({documentn} );

bulk.execute();

示例:

> var bulk = db.geekFlareCollection.initializeUnorderedBulkOp();
> bulk.insert({ code: "P1", Qty: 100, status: "Active"});
> bulk.insert({ code: "P2", Qty: 200, status: "Active"});
> bulk.insert({ code: "P3", Qty: 0, status: "Dective"});
> bulk.execute();
BulkWriteResult({
        "writeErrors" : [ ],
        "writeConcernErrors" : [ ],
        "nInserted" : 3,
        "nUpserted" : 0,
        "nMatched" : 0,
        "nModified" : 0,
        "nRemoved" : 0,
        "upserted" : [ ]
})
> db.geekFlareCollection.find()
{ "_id" : ObjectId("5edf7be318b2c26b9dfe8caf"), "code" : "P1", "Qty" : 100, "status" : "Active" }
{ "_id" : ObjectId("5edf7be318b2c26b9dfe8cb0"), "code" : "P2", "Qty" : 200, "status" : "Active" }
{ "_id" : ObjectId("5edf7be318b2c26b9dfe8cb1"), "code" : "P3", "Qty" : 0, "status" : "Dective" }
>

11. 从集合检索文档

要搜索存储在集合中的文档,可以使用find()方法。以下命令将用于从集合中检索所有文档。

  • find()方法可用于检索存储在集合中的所有文档。

语法: collectionName.find()

示例:

> db.geekFlareCollection.find()
{ "_id" : ObjectId("5ed31186b6f2c2bb1edb86ce"), "code" : "P1", "Qty" : 200, "status" : "Active" }
{ "_id" : ObjectId("5ed31186b6f2c2bb1edb86cf"), "code" : "P2", "Qty" : 200, "status" : "Active" }
{ "_id" : ObjectId("5ed31186b6f2c2bb1edb86d0"), "code" : "P3", "Qty" : 200, "status" : "Active" }
{ "_id" : ObjectId("5ed3159eb6f2c2bb1edb86d1"), "code" : "P4", "Qty" : 100, "status" : "Inactive" }
  • find({condition})方法可用于根据某些条件从集合中仅检索所需的文档。 MongoDB提供了一系列的projection and Query operators以检索BSON类型的值。

语法: collectionName.find({ condition })

示例:

> db.geekFlareCollection.find({ Qty: { $eq: 100 }});
{ "_id" : ObjectId("5ed3159eb6f2c2bb1edb86d1"), "code" : "P4", "Qty" : 100, "status" : "Inactive" }
  • 为了仅检索一个文档,MongoDB提供了findOne()方法。它提供了格式化的输出。

语法: collectionName.findOne()

示例:

> db.geekFlareCollection.findOne();
{ 
	"_id" : ObjectId("5ed31186b6f2c2bb1edb86ce"), 
        "code" : "P1",
	"Qty" : 200, 
	"status" : "Inactive" 
}

12. 美化检索输出

find()方法给出了一个杂乱的输出。 MongoDB提供pretty()命令来获得格式化的输出。

语法: collectionName.find().pretty()

示例:

> db.geekFlareCollection.find({ Qty: { $eq: 100 }}).pretty();
{
        "_id" : ObjectId("5ed3159eb6f2c2bb1edb86d1"),
        "code" : "P4",
        "Qty" : 100,
        "status" : "Inactive"
}

13. 更新集合中的文档

MongoDB提供update()方法来为文档中的现有键设置新值。更新命令提供了修改和匹配文档的详细信息。更新命令的语法如下:

语法: collectionName.update({KeyToUpdate},{Set Command})

示例:

> db.geekFlareCollection.find()
{ "_id" : ObjectId("5edf3f67d6bfbd8125f58cfb"), "product" : "bottles", "Qty" : 100 }
{ "_id" : ObjectId("5edf3f67d6bfbd8125f58cfc"), "product" : "bread", "Qty" : 20 }
{ "_id" : ObjectId("5edf3f67d6bfbd8125f58cfd"), "product" : "yogurt", "Qty" : 30 }
>
> db.geekFlareCollection.update({"product" : "bottles"},{$set : {"Qty": 10}}  )
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
>
> db.geekFlareCollection.find()
{ "_id" : ObjectId("5edf3f67d6bfbd8125f58cfb"), "product" : "bottles", "Qty" : 10 }
{ "_id" : ObjectId("5edf3f67d6bfbd8125f58cfc"), "product" : "bread", "Qty" : 20 }
{ "_id" : ObjectId("5edf3f67d6bfbd8125f58cfd"), "product" : "yogurt", "Qty" : 30 }
>
>  db.geekFlareCollection.find()
{ "_id" : ObjectId("5edf3f67d6bfbd8125f58cfb"), "product" : "bottles", "Qty" : 10 }
{ "_id" : ObjectId("5edf3f67d6bfbd8125f58cfc"), "product" : "bread", "Qty" : 20 }
{ "_id" : ObjectId("5edf3f67d6bfbd8125f58cfd"), "product" : "yogurt", "Qty" : 30 }
  • updateOne() : 要更新单个文档,可以使用updateOne()方法。updateOne()提供匹配和修改文档的计数。

语法: collectionName.updateOne({SingleKeyToUpdate},{Set Command})

示例:

> db.geekFlareCollection.updateOne({“product” : “bottles”},{$set : {“Qty”: 40}} )
{ “acknowledged” : true, “matchedCount” : 1, “modifiedCount” : 1 }

  • updateMany() : 要根据某个条件更新多个文档,MongoDB有updateMany()方法。

语法: collectionName.updateMany({filter},{Set Command})

例子:

> db.geekFlareCollection.updateMany( { "Qty" : { $lt: 30 } },{ $set: { "Qty": "Inactive"} } )
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }

14. 删除集合中的文档

为了删除文档,MongoDB提供了deleteOne()deleteMany()方法。删除方法的语法如下:

  • deleteOne({condition}) 删除满足删除条件的单个文档。

 语法: collectionName.deleteOne({DeletionCondition})

例子:

> db.geekFlareCollection.deleteOne({"product" : "bread"})
{ "acknowledged" : true, "deletedCount" : 1 }
  • deleteMany() 删除所有满足删除条件的文档。如果没有删除条件,则deleteMany({condition})将删除所有文档。

 语法: collectionName.deleteMany({DeletionCondition})

例子:

> db.geekFlareCollection.deleteMany({"product" : "bottles"})
{ "acknowledged" : true, "deletedCount" : 2 }
  • remove() 还有另一种方法可以删除所有满足删除条件的文档。remove()方法接受两个参数,一个是删除条件,另一个是一个标志位。

          注意: Remove方法在即将发布的版本中已被弃用。

语法: collectionName.remove({DeletionCondition},1)

例子:

> db.geekFlareCollection.remove({"product" : "bottles"})
WriteResult({ "nRemoved" : 1 })

15. 检索唯一记录

distinct()方法用于获取唯一记录。

  • 从一个字段获取唯一记录。

语法: collectionName.distinct(field)

例子:

> db.geekFlareCollection.distinct("product")
[ "Cheese", "Snacks2", "Snacks3", "bread", "ketchup" ]
  • 在指定查询条件的情况下从一个字段获取唯一记录。

语法: collectionName.distinct(field,query)

例子:

> db.geekFlareCollection.distinct('product',{"Qty":20})
[ "Snacks3", "bread" ]

16. 重命名集合

MongoDB提供了renameCollection ()方法来重命名集合。

语法: collectionName.renameCollection(newCollectionName)

例子:

>db.geekFlareCollection.renameCollection('geekFlareCol')
{ "ok" : 1 }
> show collections
geekFlareCol

索引

17. 在文档上创建索引

索引是一种特殊的数据结构,它以易于遍历的形式存储集合数据集的一小部分。索引支持字段值的升序和降序排序,从而在检索时提供更好的性能。

MongoDB提供了default_id索引。此外,MongoDB支持用户定义的索引的创建。MongoDB索引是在集合级别定义的,并且它支持文档的字段或子字段。创建索引的语法是:

  • 在单个字段上创建索引。

语法collectionName.createIndex({Key:1})

在此语法中,key表示要创建索引的字段,1表示升序。要创建降序索引,可以使用-1。

示例

> db.geekFlareCollection.createIndex({"product" : 1})
{
        "createdCollectionAutomatically" : false,
        "numIndexesBefore" : 1,
        "numIndexesAfter" : 2,
        "ok" : 1
}
  • 在多个字段上创建索引。

语法collectionName.createIndex({Key1:1,key2:1…keyn:1})

示例

> db.geekFlareCollection.createIndex({"product" : 1,"Qty":-1})
{
        "createdCollectionAutomatically" : false,
        "numIndexesBefore" : 1,
        "numIndexesAfter" : 2,
        "ok" : 1
}

18. 显示文档上的索引

MongoDB提供了getIndexes()方法来列出在文档上创建的所有索引。

语法collectionName.getIndexes()

示例

> db.geekFlareCollection.getIndexes()
[
        {
                "v" : 2,
                "key" : {
                        "_id" : 1
                },
                "name" : "_id_",
                "ns" : "geekFlareCollection.geekFlareCollection"
        }
]

19. 从文档中删除索引

dropIndex()方法用于删除单个索引,dropIndexes()方法用于删除多个索引。

  • 删除单个索引

语法collectionName.dropIndex({key})

示例

> db.geekFlareCollection.dropIndex({"product" : 1})
{ "nIndexesWas" : 3, "ok" : 1 }
  • 删除多个索引。

语法collectionName.dropIndexes({key1,key2…,keyN})

示例

> db.geekFlareCollection.dropIndexes({"product" : 1,"Qty":-1})
{ "nIndexesWas" : 3, "ok" : 1 }

检索相关

20. 限制检索文档

limit()方法用于限制返回的文档数量。limit()方法接受数字参数。

语法collectionName.find().limit(number)

示例

> db.geekFlareCollection.find().limit(2)
{ "_id" : ObjectId("5ed3c9e7b6f2c2bb1edb8702"), "product" : "bottles", "Qty" : 100 }
{ "_id" : ObjectId("5ed3c9e7b6f2c2bb1edb8703"), "product" : "bread", "Qty" : 20 }

21. 跳过检索文档

MongoDB支持skip()方法。该方法跳过所需数量的文档。它接受一个数字参数。

语法collectionName.find().skip(number)

示例

> db.geekFlareCollection.find().skip(2)
{ "_id" : 3, "product" : "yogurt", "Qty" : 30 }
> db.geekFlareCollection.find().skip(3)

22. 按排序检索文档

MongoDB的sort()方法按升序或降序排序输出文档。该方法接受带有数字的键名来指定排序顺序,1用于升序,而-1用于指定降序。

语法collectionName.find().sort({key:1})

示例

> db.geekFlareCollection.find().sort({"Qty":1})
{ "_id" : 2, "product" : "面包", "Qty" : 20 }
{ "_id" : 3, "product" : "酸奶", "Qty" : 30 }
{ "_id" : 1, "product" : "瓶子", "Qty" : 100 }

验证相关

23. 文档验证

验证器有助于限制插入文档中的数据类型。验证器定义在集合上。创建验证器需要使用关键字validator,以及可选的验证级别和验证操作来指定验证模式。文档验证不会限制在文档中插入新字段。

语法createCollection("collectionName",{validator:{ fields condition }})

示例:

> db.createCollection( "Login",
...  { validator: { $and:
...       [
...          { phone: { $type: "string" } },
...          { email: { $regex: /@flares.com$/ } },
...          { status: { $in: [ "Registered", "Unknown" ] } }
...       ]
...    }
... } )
{ "ok" : 1 }
>
> db.Login.insert({phone:1234})
WriteResult({
        "nInserted" : 0,
        "writeError" : {
                "code" : 121,
                "errmsg" : "文档验证失败"
        }
})
>
> db.Login.insert({phone:"1234",email:"[email protected]",status:"Unknown",mode:"limited"})
WriteResult({ "nInserted" : 1 })

24. 在新集合上创建模式验证器

需要使用附加关键字$jsonSchema,以及additional properties值设置为False来在模式级别上设置限制。它防止添加新字段到文档中。

语法createCollection("collectionName",{validator: { $jsonSchema { schema condition } }})

示例:

> db.createCollection( "Login", {
...    validator: { $jsonSchema: {
...        bsonType: "object",
...        "additionalProperties": false,
...       required: [ "email" ],
...       properties: {
...          email: {
...             bsonType : "string",
...             pattern : "@flares.com$",
...             description: "字符串满足给定表达式"
...          },
...          status: {
...             enum: [ "registered", "Invalid" ],
...             description: "状态必须在枚举值内"
...          }
...       }
...    } },
... } )
{ "ok" : 1 }
>
> db.Login.insert({email:"[email protected]"})
WriteResult({
        "nInserted" : 0,
        "writeError" : {
                "code" : 121,
                "errmsg" : "文档验证失败"
        }
})

25. 更新或创建现有集合上的模式验证器

可以使用collMod 在现有集合上创建验证器

语法runCommand({collMod:"collectionName",validator:{schema condition}})

示例:

> db.runCommand(  {
collMod: "Login",
   validator: { $jsonSchema: {
       bsonType: "object",
 "additionalProperties": false,
      required: [ "email","status" ],
      properties: {
         email: {
            bsonType : "string",
            pattern : "@flares.com$",
            description: "字符串满足给定表达式"
         },
         status: {
            enum: [ "registered", "Invalid" ],
            description: "状态必须在枚举值内"
         }
      }
   } },
      validationAction: "error",
         validationLevel: "strict"
} )
{ "ok" : 1 }

26. 删除现有集合上的模式验证器

要删除模式验证器,需要将validationLevel设置为off。

语法runCommand({collMod:”collectionName”,validator:{ },validationLevel:off})

示例:

> db.runCommand({
   collMod:"Login",
   validator:{},
   validationLevel:"off"
})
{ "ok" : 1 }
>
> db.Login.insert({"email":"abc"})
WriteResult({ "nInserted" : 1 })

27. 检查现有集合上的验证器

要检查现有集合是否具有模式验证器,请运行以下命令。未指定集合名称时,db.getCollectionInfos()方法会返回数据库中所有集合上的验证器的详细信息。

语法getCollectionInfos({name : “collectionName”})

示例:

> db.getCollectionInfos({name: "Login"})
[
        {
                "name" : "Login",
                "type" : "collection",
                "options" : {
                        "validator" : {
                                "email" : {
                                        "$regex" : /@flares.com$/
                                }
                        }
                },
                "info" : {
                        "readOnly" : false,
                        "uuid" : UUID("646674f6-4b06-466d-93b0-393b5f5cb4ff")
                },
                "idIndex" : {
                        "v" : 2,
                        "key" : {
                                "_id" : 1
                        },
                        "name" : "_id_",
                        "ns" : "geekFlareDB.Login"
                }
        }
]

游标相关

28. MongoDB中的游标

游标是用于迭代结果集的指针。MongoDB使用hasNext()forEach()方法进行迭代。提供了一些链接的列表。

示例:

> var newCursor=db.geekFlareCollection.find()
> newCursor.forEach(printjson)
{ "_id" : 1, "product" : "bottles", "Qty" : 100 }
{ "_id" : 2, "product" : "bread", "Qty" : 20 }
{ "_id" : 3, "product" : "yogurt", "Qty" : 30 }
>
> var newCursor1=db.geekFlareCollection.find()
> while(newCursor1.hasNext()){ printjson(newCursor1.next())}
{ "_id" : 1, "product" : "bottles", "Qty" : 100 }
{ "_id" : 2, "product" : "bread", "Qty" : 20 }
{ "_id" : 3, "product" : "yogurt", "Qty" : 30 

实用程序

29. 备份数据库

mongodump实用程序用于将MongoDB数据库的内容导出为备份。该命令从系统控制台而不是mongo shell运行。它将生成二进制备份以及元数据信息。

语法

mongodump --db dbName --out outFile --host "IP:PORT"  --username   --password

示例:

C:mongodbdump>mongodump –db geekFlareDB –out “C:mongodbdump” –host “127.0.0.1:27017”
2020-06-02T12:26:34.428+0530 正在将 geekFlareDB.myTable 写入
2020-06-02T12:26:34.430+0530 正在将 geekFlareDB.geekFlareCollection 写入
2020-06-02T12:26:34.430+0530 正在将 geekFlareDB.mCollection 写入
2020-06-02T12:26:34.433+0530 正在将 geekFlareDB.users 写入
2020-06-02T12:26:34.434+0530 完成对 geekFlareDB.myTable 的导出 (2 个文档)
2020-06-02T12:26:34.434+0530 完成对 geekFlareDB.geekFlareCollection 的导出 (4 个文档)
2020-06-02T12:26:34.435+0530 正在将 geekFlareDB.contacts2 写入
2020-06-02T12:26:34.435+0530 正在将 geekFlareDB.Login 写入
2020-06-02T12:26:34.436+0530 完成对 geekFlareDB.mCollection 的导出 (2 个文档)
2020-06-02T12:26:34.437+0530 完成对 geekFlareDB.users 的导出 (1 个文档)
2020-06-02T12:26:34.437+0530 完成对 geekFlareDB.Login 的导出 (0 个文档)
2020-06-02T12:26:34.438+0530 完成对 geekFlareDB.contacts2 的导出 (0 个文档)

30. 从备份中恢复数据库

使用 mongorestore 实用工具可以恢复 mongodump 生成的二进制数据。

语法: mongorestore --db newDB "pathOfOldBackup"

示例:

C:Usersasad.ali>mongorestore  --db geekFlareNew  "C:mongodbdumpgeekFlare" --host "127.0.0.1:27017"
2020-06-09T15:49:35.147+0530    当恢复来自 BSON 文件的数据时,只应使用 --db 和 --collection 参数。其他用法已被弃用,并将在将来不再存在;请改用 --nsInclude
2020-06-09T15:49:35.148+0530    正在构建要从 C:mongodbdumpgeekFlare 目录恢复的集合列表
2020-06-09T15:49:35.152+0530    从 C:mongodbdumpgeekFlaregeekFlareCollection.metadata.json 读取 geekFlareNew.geekFlareCollection 的元数据
2020-06-09T15:49:35.321+0530    从 C:mongodbdumpgeekFlaregeekFlareCollection.bson 恢复 geekFlareNew.geekFlareCollection
2020-06-09T15:49:35.461+0530    没有要恢复的索引
2020-06-09T15:49:35.462+0530    完成对 geekFlareNew.geekFlareCollection 的恢复 (3 个文档, 0 个失败)
2020-06-09T15:49:35.467+0530    成功恢复了 3 个文档。0 个文档恢复失败。

31. 导出集合

为了将集合的内容导出到文件 (JSON 或 CSV),提供了 mongoexport 实用工具。要运行此命令,请使用系统终端。

  • 将单个集合导出到文件。

语法: mongoexport --db dbName --collection collectionName --out outputFile

示例:

C:mongodbNew folder>mongoexport --db geekFlareDB --collection geekFlareCol --out outFile.json
2020-06-06T19:02:29.994+0530    已连接到: mongodb://localhost/
2020-06-06T19:02:30.004+0530    导出了 6 条记录
  • 将集合中的特定字段导出到文件。

语法: mongoexport --db dbName --collection collectionName --out outputFile --fields fieldname

示例:

C:mongodbNew folder>mongoexport --db geekFlareDB --collection geekFlareCol --out outFile.json --fields product
2020-06-06T19:05:22.994+0530    已连接到: mongodb://localhost/
2020-06-06T19:05:23.004+0530    导出了 6 条记录

32. 导入集合

要从文件 (CSV 或 JSON) 导入数据,可以使用 mongoimport 命令行工具。

语法: mongoimport --db dbName --collection collectionName --file inputFile

C: Users asad.ali> mongoimport –db geekFlareDB –collection geekFlareNew –file outFile.json
2020-06-09T14: 52: 53.655 + 0530已连接到:mongodb:// localhost /
2020-06-09T14: 52: 53.924 + 0530成功导入6个文档。 未能导入0个文档。

与副本相关

复制与分片不同,请查看此指南implement Sharding

33. MongoDB副本集

复制是将数据同步到多个服务器的过程。它可以防止由于硬件或软件故障而导致的数据丢失。 MongoDB使用副本集实现复制。副本集由群集中的主要和次要Mongo数据集组成。

主数据集接受所有写操作,而次要数据集从主数据集读取。Mongo副本集中需要至少3个数据集。设置副本集需要以下步骤:

  • 在至少3个节点上使用replset选项启动mongod服务器。

mongod --port 27017 --dbpath C: data data1 --replSet rs0 --oplogSize 128

mongod --port 27018 --dbpath C: data data1 --replSet rs0 --oplogSize 128

mongod --port 27019 --dbpath C: data data1 --replSet rs0 --oplogSize 128

  • 初始化副本集。

rs.initiate({ _id:“rs0”,members:[{ _id:0,host:“IP:27017”},{ _id:1,host:“IP:27018”},{ _id:2,host:“IP:27019”} ]})

> rs.initiate({
...... _id:“rs0”,
......成员:[
...... { _id:0,host:“localhost:27017”},
...... { _id:1,host:“localhost:27018”},
...... { _id:2,host:“localhost:27019”}
...... ]
......})
{
“好”的:1,
“$ clusterTime”:{
“clusterTime”:Timestamp(1591089166,1),
“signature”:{
“hash”:BinData(0,“AAAAAAAAAAAAAAAAAAAAAAAAAAA =”),
“keyId”:NumberLong(0)
}
},
“operationTime”:Timestamp(1591089166,1)
}  

34.检查复制的状态

从主复制节点运行以下命令以获取副本集的完整信息。

rs.conf()

rs.status()

35. 将新的MongoDB实例添加到副本集

启动主要的MongoDB客户端并运行以下命令

语法: rs.add("主机名:端口号")

示例:

rs0:PRIMARY> rs.add("localhost:27016")
{
        "ok" : 1,
        "$clusterTime" : {
                "clusterTime" : Timestamp(1591094195, 1),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        },
        "operationTime" : Timestamp(1591094195, 1)
}

36. 从副本集中移除已存在的MongoDB实例

以下命令将从副本集中移除所需的次要主机。

语法: rs.remove("localhost:27017")

示例:

rs0:PRIMARY> rs.remove("localhost:27016")
{
        "ok" : 1,
        "$clusterTime" : {
                "clusterTime" : Timestamp(1591095681, 1),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        },
        "operationTime" : Timestamp(1591095681, 1)
}
rs0:PRIMARY>

 37. 将主节点设置为辅助节点副本集

MongoDB提供了一个命令,用于指示主节点副本成为辅助节点副本集。

语法: rs.stepDown( stepDownSecs , secondaryCatchupSecs )

示例:

rs0:PRIMARY> rs.stepDown(12)
{
        "ok" : 1,
        "$clusterTime" : {
                "clusterTime" : Timestamp(1591096055, 1),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        },
        "operationTime" : Timestamp(1591096055, 1)
}
rs0:SECONDARY>

38. 检查主节点和辅助节点之间的复制延迟

使用以下命令可以检查主节点和所有辅助节点之间的复制延迟。

语法: rs.printSlaveReplicationInfo()

示例:

rs0:PRIMARY> rs.printSlaveReplicationInfo()
source: localhost:27018
        syncedTo: Tue Jun 02 2020 16:14:04 GMT+0530 (India Standard Time)
        0秒(0小时)滞后于主节点
source: localhost:27019
        syncedTo: Thu Jan 01 1970 05:30:00 GMT+0530 (India Standard Time)
        1591094644秒(441970.73小时)滞后于主节点
source: localhost:27016
        syncedTo: Tue Jun 02 2020 16:14:04 GMT+0530 (India Standard Time)
        0秒(0小时)滞后于主节点
rs0:PRIMARY>

与事务相关

39. MongoDB中的事务

MongoDB支持对文档进行事务的ACID特性。

要启动一个事务,需要先启动一个会话,并且需要提交以将更改保存到数据库中。事务支持在副本集或mangos上进行。一旦会话成功提交,会话内部进行的操作将在外部可见。

  • 开始会话

语法: session =db.getMongo().startSession()

  • 开始事务

语法: session.startTransaction()

  • 提交事务

语法: session.commitTransaction()

示例:

让我们创建一个会话,开始事务,执行一些插入/更新操作,然后提交事务。

如果两个事务试图更新同一文档,MongoDB会抛出写冲突错误。

“`html
rs0:PRIMARY> session1.startTransaction()
rs0:PRIMARY> session2.startTransaction()
rs0:PRIMARY> session1.getDatabase(“geekFlareDB”).geekFlareCollection.update({_id:3},{$set:{ product: “Bread” }})
WriteResult({ “nMatched” : 1, “nUpserted” : 0, “nModified” : 1 })
rs0:PRIMARY> session2.getDatabase(“geekFlareDB”).geekFlareCollection.update({_id:3},{$set:{ product: “Snacks” }})
WriteCommandError({
“errorLabels” : [
“TransientTransactionError”
],
“operationTime” : Timestamp(1591174593, 1),
“ok” : 0,
“errmsg” : “WriteConflict”,
“code” : 112,
“codeName” : “WriteConflict”,
“$clusterTime” : {
“clusterTime” : Timestamp(1591174593, 1),
“signature” : {
“hash” : BinData(0,”AAAAAAAAAAAAAAAAAAAAAAAAAAA=”),
“keyId” : NumberLong(0)
}
}
})
rs0:PRIMARY>
“`

MongoDB在单个会话中支持多文档事务。

“`html
db.getMongo().startTransaction()

// 在多个文档上执行一些插入/更新操作

session.commitTransaction()
“`

示例:

42. 在MongoDB中进行分析

分析有助于在system.profile集合中记录慢查询。 Profiler level和采样率定义了要在system.profile集合中记录的查询的百分比。

  • 设置/获取分析级别

语法

db.setProfilingLevel(profilingLevel,{"slowms":time,"sampleRate":LoggingPercentage})

> db.setProfilingLevel(2,{"slowms":1,"sampleRate":1})
{ "was" : 1, "slowms" : 1, "sampleRate" : 0.5, "ok" : 1 }
>
> db.getProfilingLevel()
2
  • 获取分析状态

语法:db.getProfilingStatus()

> db.getProfilingStatus()
{ "was" : 2, "slowms" : 1, "sampleRate" : 1 }
  • 要在MongoDB实例级别启用分析,请使用携带分析器信息启动实例,或在配置文件中添加分析器详细信息。

语法

mongod --profile --slowms --slowOpSampleRate

例子

C:WindowsSystem32>mongod  --port 27017 --dbpath C:datadata1  --profile 1 --slowms 25 --slowOpSampleRate  0.5
2020-06-09T02:34:41.110-0700 I  CONTROL  [main] Automatically disabling TLS 1.0, to force-enable TLS 1.0 specify --sslDisabledProtocols 'none'
2020-06-09T02:34:41.113-0700 W  ASIO     [main] No TransportLayer configured during NetworkInterface startup
2020-06-09T02:34:41.113-0700 I  CONTROL  [initandlisten] MongoDB starting : pid=22604 port=27017 dbpath=C:datadata1 64-bit host=MCGL-4499
2020-06-09T02:34:41.114-0700 I  CONTROL  [initandlisten] targetMinOS: Windows 7/Windows Server 2008 R2
2020-06-09T02:34:41.116-0700 I  CONTROL  [initandlisten] db version v4.2.7
2020-06-09T02:34:41.116-0700 I  CONTROL  [initandlisten] git version: 51d9fe12b5d19720e72dcd7db0f2f17dd9a19212 

43. MongoDB的Explain()方法

MongoDB的explain()方法返回统计信息,并提供选择一个优胜方案并将其执行到完成的信息。它根据verbosity plan.返回结果

语法collectionName.explain("verbosityName")

要执行explain()方法/命令,让我们创建一个verbosity,然后执行explain()方法,查看下面的示例,其中执行了这些步骤。

例子

> db.runCommand(
… {
… explain: { count: “product”, query: { Qty: { $gt: 10 } } },
… verbosity: “executionStats”
… }
… )
{
“queryPlanner” : {
“plannerVersion” : 1,
“namespace” : “test.product”,
“indexFilterSet” : false,
“winningPlan” : {
“stage” : “COUNT”,
“inputStage” : {
“stage” : “EOF”
}
},
“rejectedPlans” : [ ] },
“executionStats” : {
“executionSuccess” : true,
“nReturned” : 0,
“executionTimeMillis” : 47,
“totalKeysExamined” : 0,
“totalDocsExamined” : 0,
“executionStages” : {
“stage” : “COUNT”,
“nReturned” : 0,
“executionTimeMillisEstimate” : 0,
“works” : 1,
“advanced” : 0,
“needTime” : 0,
“needYield” : 0,
“saveState” : 0,
“restoreState” : 0,
“isEOF” : 1,
“nCounted” : 0,
“nSkipped” : 0,
“inputStage” : {
“stage” : “EOF”,
“nReturned” : 0,
“executionTimeMillisEstimate” : 0,
“works” : 0,
“advanced” : 0,
“needTime” : 0,
“needYield” : 0,
“saveState” : 0,
“restoreState” : 0,
“isEOF” : 1
}
}
},
“serverInfo” : {
“host” : “MCGL-4499”,
“port” : 27017,
“version” : “4.2.7”,
“gitVersion” : “51d9fe12b5d19720e72dcd7db0f2f17dd9a19212”
},
“ok” : 1
}
> var expv = db.geekFlareCol.explain(“executionStats”)
> expv.find( { product: “bread”} )
{
“queryPlanner” : {
“plannerVersion” : 1,
“namespace” : “geekFlareDB.geekFlareCol”,
“indexFilterSet” : false,
“parsedQuery” : {
“product” : {
“$eq” : “bread”
}
},
“winningPlan” : {
“stage” : “COLLSCAN”,
“filter” : {
“product” : {
“$eq” : “bread”
}
},
“direction” : “forward”
},
“rejectedPlans” : [ ] },
“executionStats” : {
“executionSuccess” : true,
“nReturned” : 2,
“executionTimeMillis” : 0,
“totalKeysExamined” : 0,
“totalDocsExamined” : 6,
“executionStages” : {
“stage” : “COLLSCAN”,
“filter” : {
“product” : {
“$eq” : “bread”
}
},
“nReturned” : 2,
“executionTimeMillisEstimate” : 0,
“works” : 8,
“advanced” : 2,
“needTime” : 5,
“needYield” : 0,
“saveState” : 0,
“restoreState” : 0,
“isEOF” : 1,
“direction” : “forward”,
“docsExamined” : 6
}
},
“serverInfo” : {
“host” : “MCGL-4499”,
“port” : 27017,
“version” : “4.2.7”,
“gitVersion” : “51d9fe12b5d19720e72dcd7db0f2f17dd9a19212”
},
“ok” : 1
}
>

与访问控制相关

44. MongoDB的访问控制

访问控制功能可以对现有用户进行身份验证访问。对于启用了访问控制的数据库,请确保在admin数据库中创建一个用户管理员角色。

  • 无认证连接到数据库。
  • 切换到数据库

use admin

  • 按照以下方式创建用户

db.createUser( {user: "UserAdmin", pwd: "password" ,role: [adminRole])

示例:

db.createUser(
...   {
...     user: "AdminUser",
...     pwd: passwordPrompt(),
...     roles: [ { role: "userAdminAnyDatabase", db: "admin" }, "readWriteAnyDatabase" ]
...   }
... )
Enter password:
Successfully added user: {
        "user" : "AdminUser",
        "roles" : [
                {
                        "role" : "userAdminAnyDatabase",
                        "db" : "admin"
                },
                "readWriteAnyDatabase"
        ]
}
  • 重新启动mongod实例
  • 再次使用创建的用户和密码访问。
C:Users>mongo  --port 27017  --authenticationDatabase "admin" -u "AdminUser" -p
MongoDB shell version v4.2.7
Enter password:
connecting to: mongodb://127.0.0.1:27017/?authSource=admin&compressors=disabled&gssapiServiceName=mongodb

45. 检索和删除访问控制用户

可以使用以下命令来检查用户信息和删除用户。

  • db.getUser("AdminUser")
  • db.dropUser("AdminUser")

示例:

> db.getUser(“AdminUser”)
{
“_id” : “admin.AdminUser”,
“userId” : UUID(“78d2d5bb-0464-405e-b27e-643908a411ce”),
“user” : “AdminUser”,
“db” : “admin”,
“roles” : [
{
“role” : “userAdminAnyDatabase”,
“db” : “admin”
},
{
“role” : “readWriteAnyDatabase”,
“db” : “admin”
}
],
“mechanisms” : [
“SCRAM-SHA-1”,
“SCRAM-SHA-256”
] }
> db.dropUser(“AdminUser”)
true
> db.getUser(“AdminUser”)
null

46. 授予用户自定义角色

MongoDB提供了db.createRole()方法来为用户指定权限和继承角色的数组。

  • 使用admin用户连接MongoDB实例。
  • 执行以下命令生成新角色。

语法:

db.createRole({role:”roleName”,privileges:[{privilegeName}],roles:[InheritedArray]})

示例:

use admin
> db.createRole(
...    {
...      role: "abc",
...      privileges: [ { resource: { db: "geekFlareDB", collection: "geekFlareCol" }, actions: [ "killop" ,"inprog"] } ],
...      roles: []
...    }
... )
{
        "role" : "abc",
        "privileges" : [
                {
                        "resource" : {
                                "db" : "geekFlareDB",
                                "collection" : "geekFlareCol"
                        },
                        "actions" : [
                                "killop",
                                "inprog"
                        ]
                }
        ],
        "roles" : [ ]
}

47. 撤销用户自定义角色

使用以下命令修改现有角色。

语法: db.revokeRolesFromUser( userName, [{ "role" : roleName , db:dbName} ] )

示例:

> db.getUser("AdminUser")
{
        "_id" : "admin.AdminUser",
        "userId" : UUID("fe716ed1-6771-459e-be13-0df869c91ab3"),
        "user" : "AdminUser",
        "db" : "admin",
        "roles" : [
                {
                        "role" : "userAdminAnyDatabase",
                        "db" : "admin"
                },
                {
                        "role" : "readWriteAnyDatabase",
                        "db" : "admin"
                }
        ],
        "mechanisms" : [
                "SCRAM-SHA-1",
                "SCRAM-SHA-256"
        ]
}
> db.revokeRolesFromUser( "AdminUser", [{ "role" : "userAdminAnyDatabase" , db:"admin"} ] )
> db.getUser("AdminUser")
{
        "_id" : "admin.AdminUser",
        "userId" : UUID("fe716ed1-6771-459e-be13-0df869c91ab3"),
        "user" : "AdminUser",
        "db" : "admin",
        "roles" : [
                {
                        "role" : "readWriteAnyDatabase",
                        "db" : "admin"
                }
        ],
        "mechanisms" : [
                "SCRAM-SHA-1",
                "SCRAM-SHA-256"
        ]
}
>

48. 使用Python连接MongoDB

需要pymongo包才能从Python控制台连接MongoDB。

>>> from pymongo import MongoClient
>>> mClient=MongoClient("mongodb://127.0.0.1:27017/")
>>> mDB=mClient.geekFlareDB
>>> mRecord={"_id":4,"name":"XYZ"}
>>> mDB.geekFlareCollection.insert_one(mRecord)

>>> for i in mDB.geekFlareCollection.find({"_id":4}):
...     print(i)
...
{'_id': 4, 'name': 'XYZ'}
>>>

接下来是什么?

查看这个链接列表来管理MongoDB和其他NoSQL数据库。如果您的工作经常涉及到与MongoDB的工作,那么您可能想要从这个链接中学到更多知识。

类似文章