mongodb4.2.x教程

mongo4.2.x教程

- - -来自mongodb中文教程(搬运整理)

1. mongo 命令行

通过JavaScript接口和MongoDB进行交互。您可以使用mongo shell去查询和更新数据以及执行管理操作。

在MongoDB服务安装时就已集成。MongoDB还提供mongo shell作为一个独立的包。下载独立mongo shell包:

  1. 打开下载中心。对于企业mongo Shell,选择MongoDB Enterprise Server选项卡。

  2. 从下拉框选择适合您的版本和操作系统

3.选择适合您的操作系统进行下载

Platform平台 Download Package 下载包

  • windows选择zip包进行下载
  • macOS选择TGZ包进行下载
  • linux选择shell包进行下载

一旦安装并启动MongoDB,就可以通过mongo shell去运行MongoDB实例。

注意,从MongoDB 4.0.13和4.2版本开始,当连接和官方MongoDB有区别的非官方MongoDB实例时,mongo shell 将提示警告信息;例如缺少或不完整功能,或不一样的功能。

开始用mongo shell连接MongoDB,前提:

尝试启动mongo shell时,确保MongoDB已经运行。打开终端窗口(或Windows命令提示符)并进入<安装mongodb 目录 > / bin目录:

cd <mongodb installation dir>/bin

小提示,添加MongoDB安装目录下的bin目录到系统环境变量中,这样你可以在任何地方执行mongo命令行,而不需要到MongoDB安装目录去执行。

用默认端口连接本地MongoDB实例,默认不添加任何参数,执行如下mongo命令,以27012端口连接MongoDB实例:

mongo

用非默认端口连接本地实例,以–port 命令行方式指定端口启动MongoDB实例。例如用一个非默认的28015端口启动MongoDB实例:

mongo --port 28015

连接远程MongoDB实例,指定主机名和/或端口,您可以指定一个连接字符串。例如,连接MongoDB实例运行在远程主机上

mongo "mongodb://mongodb0.example.com:28015"
  • 您可以使用命令行选项 --host <host>:<port>。例如,连接远程主机的MongoDB实例:
mongo --host mongodb0.example.com:28015
  • 您可以使用--host <host> and --port <port>命令行选项进行连接。例如,连接远程主机的MongoDB实例:
mongo --host mongodb0.example.com --port 28015

启用身份验证的MongoDB实例,连接到需要身份验证的MongoDB实例:

  • 您可以在连接信息中指定用户名、身份验证信息以及密码。例如,连接远程MongoDB实例以alice作为用户进行身份验证

注意,如果您没有在连接字符串中指定密码,shell将提示输入密码

mongo "mongodb://alice@mongodb0.examples.com:28015/?authSource=admin"
  • 您可以使用--username <user>--password——authenticationDatabase < db >命令行选项进行连接。例如,连接远程MongoDB实例以alice作为用户进行身份验证

注意,如果您输入--password后面没有用户密码,shell将提示输入密码

mongo --username alice --password --authenticationDatabase admin --host mongodb0.examples.com --port 28015

连接到MongoDB副本集, 连接到副本集:

  • 您可以在连接字符串中指定副本集名称和成员。
mongo "mongodb://mongodb0.example.com.local:27017,mongodb1.example.com.local:27017,mongodb2.example.com.local:27017/?replicaSet=replA"
mongo "mongodb+srv://server.example.com/"

注意

使用+srv字符串修正符进行连接,会自动设置ssl选项为true。

  • 您可以指定副本集名称和成员以——host<副本集名称> / < host1 >: <port1 >、< host2 >: <port2 >,……命令行方式。例如,连接到名称为replA的副本集:
mongo --host replA/mongodb0.example.com.local:27017,mongodb1.example.com.local:27017,mongodb2.example.com.local:27017

TLS/SSL连接

  • 为了TLS/SSL连接,您可以在连接字符串中指定ssl = true。
mongo "mongodb://mongodb0.example.com.local:27017,mongodb1.example.com.local:27017,mongodb2.example.com.local:27017/?replicaSet=replA&ssl=true"
mongo "mongodb+srv://server.example.com/"

注意:

使用+srv字符串修正符进行连接,会自动设置ssl选项为true。

  • 您可以指定--ssl命令行选项。例如,连接到名称为replA的副本集:
mongo --ssl --host replA/mongodb0.example.com.local:27017,mongodb1.example.com.local:27017,mongodb2.example.com.local:27017

最后:

想获取更多关于连接示例中使用的参数选项以及其他参数选项,可以到mongo参考 和启动启动MongoDB示例中进行查询。

使用mongo shell

查看您所使用的数据库,数据库类型:

db

该操作会返回测试库,这是默认的数据库。 如下示例,切换数据库使用 use <db>命令

use <database>

在不切换数据库上下文环境的情况下,可以使用db.getSiblingDB()访问其他数据库,[1]使用show dbs列出该用户可用的数据库。你可以切换到不存在的数据库。当你第一次将数据存储在不存在的数据库中,如创建一个collection,则数据库和集合会一并创建。例如,下面在执行insertOne()时会创建数据库myNewDatabase和集合myCollection:

use myNewDatabase
db.myCollection.insertOne( { x: 1 } );

db.myCollection.insertOne()是mongo shell可用的方法之一。

  • database.db是指当前数据库。

  • myCollection是集合名词。

如果mongo shell不识别一个集合名称,您可以使用替代语法db.getCollection()。例如,如果一个集合名称包含一个空格或连字符,或以一个数字开头,或与一个内置函数冲突:

db.getCollection("3 test").find()
db.getCollection("3-test").find()
db.getCollection("stats").find()

mongo shell限制每行4095个字符,如果超过4095个字符,mongo shell会进行截断。

mongo shell中更多关于MongoDB的基本操作,如下:

[2]如果以访问控制的方式部署运行,根据用户权限的不同会返回不同的结果。有关详细信息,请参阅listDatabases细节

格式化打印结果

db.collection.find()方法返回一个游标结果;然而,在mongo shell中,如果返回的游标不使用var关键字分配给一个变量,然后光标会自动打印与查询匹配的前20个文档。接着mongo shell将提示输入游标继续打印后面的20个文档。

您可以添加.pretty()来格式打印结果,如下:

db.myCollection.find().pretty()

此外,您可以在mongo shell使用以下更明确的打印方法:

  • print()打印非格式化的数据

  • printjson() print(tojson(<obj>)) 和 printjson() 一样打印JSON格式数据

更多关于游标mongo shell的操作,可以参考在mongo shell中see 迭代游标章节。也可在mongo shell中查看游标帮助列表。

多行操作

如果您以(’(’)、(’{’)、(’[’)结束,那么后续行会以省略号("…")开始,直到您输入相应的(’)’)、(’}’)、(’]’)才会结束。mongo shell直到关闭符号(’)’)、(’}’)、(’]’),才会执行,像下面的例子:

> if ( x > 0 ) {
... count++;
... print (x);
... }

输入两个空行您可以退出行延续模式,像下面的例子:

> if (x > 0
...
...
>

补全和其他快捷键

mongo shell支持快捷键

  • documentation for more information on the .dbshell file. 使用向上/向下箭头键滚动命令历史。可以到 .dbshell文档了解更多信息

  • 使用<tap>自动完成或者列出可能的列表,如以下示例使用<tap>自动补全以字母’c’开头的方法:

db.myCollection.c<Tab>

因为有很多集和方法以字母’c’开头, <tap>将列出各种以’c’开头的方法。 到Shell Keyboard Shortcuts查看完整快捷键列表

.mongorc.js File .mongorc.js文件

当启动时,MongoDB会检查用户的主目录的一个名为.mongorc.js的JavaScript文件,如果存在,会在第一次命令行提示前执行该js文件。如果用mongo shell 执行JavaScript文件或JavaScript表达式,或者通过–eval执行,或者创建一个a .js文件执行,在这些JavaScript执行完,会执行.mongorc.js文件。您可以使用–norc 防止.mongorc.js被执行。

eixt 退出shell

用 quit()或者<Ctrl-C>快捷键退出shell



2. 批量写操作

本页面中

Overview

MongoDB使客户端能够批量执行写操作。 批量写入操作会影响单个集合。 MongoDB允许应用程序确定批量写入操作所需的可接受的确认级别。

3.2版本新增

db.collection.bulkWrite()方法提供了执行批量插入,更新和删除操作的能力。对于批量插入而言,MongoDB也支持db.collection.insertMany()

Ordered vs Unordered Operations 有序 VS 无序操作

批量写操作可以是ordered,也可以unordered

使用操作的有序列表,MongoDB串行地执行操作。 如果在某个单独的写操作的处理过程中发生错误,MongoDB将直接返回而不再继续处理列表中任何剩余的写操作。 请参考ordered Bulk Write

使用无序的操作列表,MongoDB可以并行地执行操作,但是不能保证此行为。 如果某个单独的写操作的处理过程中发生错误,MongoDB将继续处理列表中剩余的写操作。 请参考Unordered Bulk Write


在分片集合上执行有序的批量写操作通常比执行无序批量写操作要慢。这是因为对于有序列表而言,每个操作都必须等待上一个操作完成后才能执行。

默认情况下, bulkWrite()执行有序的写入。 要指定无序的写入,请在选项文档中设置ordered:false

请参考操作的执行

bulkWrite() Methods bulkWrite()方法

bulkWrite()支持如下操作:

要执行下面这一系列写操作:

characters集合包含以下文档:

{ "_id" : 1, "char" : "Brisbane", "class" : "monk", "lvl" : 4 },
{ "_id" : 2, "char" : "Eldon", "class" : "alchemist", "lvl" : 3 },
{ "_id" : 3, "char" : "Meldane", "class" : "ranger", "lvl" : 3 }

接下来的bulkWrite() 将在此集合上执行批量写入的操作。

try {
   db.characters.bulkWrite(
      [
         { insertOne :
            {
               "document" :
               {
                  "_id" : 4, "char" : "Dithras", "class" : "barbarian", "lvl" : 4
               }
            }
         },
         { insertOne :
            {
               "document" :
               {
                  "_id" : 5, "char" : "Taeln", "class" : "fighter", "lvl" : 3
               }
            }
         },
         { updateOne :
            {
               "filter" : { "char" : "Eldon" },
               "update" : { $set : { "status" : "Critical Injury" } }
            }
         },
         { deleteOne :
            { "filter" : { "char" : "Brisbane"} }
         },
         { replaceOne :
            {
               "filter" : { "char" : "Meldane" },
               "replacement" : { "char" : "Tanys", "class" : "oracle", "lvl" : 4 }
            }
         }
      ]
   );
}
catch (e) {
   print(e);
}

该操作将返回如下的结果:

{
   "acknowledged" : true,
   "deletedCount" : 1,
   "insertedCount" : 2,
   "matchedCount" : 2,
   "upsertedCount" : 0,
   "insertedIds" : {
      "0" : 4,
      "1" : 5
   },
   "upsertedIds" : {

   }
}

想了解更多例子,请参考bulkWrite() Examples

Strategies for Bulk Inserts to a Sharded Collection 分片集合的批量插入策略

大量的插入操作(包括初始数据插入或者定时的数据导入)可能会影响分片集群分片集群的性能。对于批量插入,请考虑以下策略:

Pre-Split the Collection 对分片集合进行预拆分

如果分片集合为空,则该集合只有一个存储在单个分片上的初始数据块,MongoDB必须花一些时间来接收数据,创建拆分并将拆分的块分发到其他分片上。为了避免这种性能开销,您可以对分片集合进行预拆分,请参考分片集群中的数据块拆分中的描述。

Unordered Writes to mongos 对mongos的无序写入

要提高对分片集群的写入性能,请使用带有可选参数ordered set to falsebulkWrite()方法。mongos 会尝试同时将写入发送到多个分片。对于空集合,请首先按照在分片集群中拆分数据块中描述的进行集合的预拆分。

Avoid Monotonic Throttling 避免单调插入带来的瓶颈

如果您的分片键在插入过程中是单调增加的,那么所有插入的数据都会插入到该分片集合的最后一个数据块中,也就是说会落到某单个分片上。因此,集群的插入能力将永远不会超过该单个分片的插入性能(木桶的短板原理)。

如果插入量大于单个分片可以处理的数据量,并且无法避免单调增加的分片键,那么可以考虑对应用程序进行如下修改:

-翻转分片键的二进制位。这样可以保留信息的同时避免插入顺序与递增插入值之间的关联性。

  • 交换第一个和最后16比特来实现“shuffle”插入。

示例

下面的C++例子中,交换了生成BSON ObjectIds的前16和末尾16比特值,因此它不再是单调递增的。

using namespace mongo;
OID make_an_id() {
  OID x = OID::gen();
  const unsigned char *p = x.getData();
  swap( (unsigned short&) p[0], (unsigned short&) p[10] );
  return x;
}

void foo() {
  // create an object
  BSONObj o = BSON( "_id" << make_an_id() << "x" << 3 << "name" << "jane" );
  // now we may insert o into a sharded collection
}

另请参考

Shard Keys来获得如何选择分片键的相关信息。另请参考Shard Key Internals(尤其是其中选择一个分片键的相关章节)




3.Read Concern

在本页中

readConcern(读关注) 选项允许你控制从副本集和分片集读取数据的一致性和隔离性。

通过有效地使用write concerns和readConcern,你可以适当地调整一致性和可用性的保证级别,例如等待以保证更强的一致性,或放松一致性要求以提供更高的可用性。

将MongoDB驱动程序更新到MongoDB 3.2或更高版本以支持读关注。

读关注级别

以下为可用的读关注级别:

levelDescription
"local"查询并从实例返回数据,但不能保证该数据已被写入大多数副本集成员(即可能已经回滚)。

默认为:
针对主节点读。
如果读取与因果一致的会话相关联,则针对副节点读。

可用性:
读关注local可用于有或没有因果关系一致的会话和事务中。

更多的信息,请参考"local"
"available"查询并从实例返回数据,但不能保证该数据已被写入大多数副本集成员(即可能已经回滚)。

默认为: 如果读取与因果关系一致的会话没有关联,则针对副节点读

可用性: 读关注available无法用于有因果关系一致的会话和事务中。

对于分片群集,"available"读关注提供了各种读关注中尽可能最低的延迟。但是,这是以牺牲一致性为代价的,因为从分片的集合中进行读取时,"available"读关注会返回孤立的文档。为了避免从分片的集合中读取时返回孤立文档的风险,可使用其他读关注,如"local"读关注。

更多的信息,请参考"available"

3.6版本的新功能
"majority"该查询返回大多数副本集成员已确认的数据。读操作返回的文档即使在发生故障的情况下也可用。
为了满足读关注“majority”,副本集成员从其内存视图中返回多数提交点提交的数据。这样,读关注"majority"在性能成本上可与其他读关注相媲美。


可用性:
 读关注"majority"可用于有或没有因果关系一致的会话和事务中。
对于具有三名成员的主从仲裁(PSA)架构的部署,可以禁用读关注"majority";但是,这对change streams(仅在MongoDB 4.0和更早版本中)和分片群集上的事务有影响。有关更多信息,请参见禁用读关注Marjority.。

要求: 若要使用"majority"读关注级别,副本集必须使用WiredTiger存储引擎

注意:
对于多文档事务中的操作,仅当事务以写关注"majority"提交时,读关注"majority"才提供其保证。否则,"majority"读关注不能保证其在事务中读取的数据。

更多的信息,请参考"majority"
"linearizable"该查询返回的数据表示了这些数据在操作开始之前已成功在大多数节点确认写入。查询可能会等待并发执行的写操作传播到大多数副本集成员,然后返回结果。

如果大多数副本集成员崩溃并在读操作后重新启动,则如果将writeConcernMajorityJournalDefault设置为默认状态true,则读操作返回的文档将还是有效的。
writeConcernMajorityJournalDefault设置为false时,MongoDB不会等待w: "majority"在确认写入之前先要写入磁盘日志。这样,如果给定副本集中大多数节点的瞬时丢失(例如崩溃和重新启动),majority写操作可能会回滚。


可用性:
读关注"linearizable"不适用于因果一致的会话和事务。
你可以仅对主节点上的读操作指定为线性读关注。

你不能将$out$merge操作与读关注"linearizable"结合使用。也就是说,如果为db.collection.aggregate()指定为"linearizable"读关注,则不能在管道中使用任何的操作。

要求: linearizable读关注仅保证在读操作指定了唯一标识单个文档的查询过滤器时可用。

TIP:
请始终将maxTimeMS与linearizable读关注一起使用,以防止大多数数据承载成员不可用。maxTimeMS确保操作不会无限期地阻塞,而是确保如果无法满足读取要求,则操作将返回错误。
更多的信息,请参考"linearizable"
"snapshot"如果事务不是因果一致会话的一部分,写关注为"majority"且在事务提交后,可以确保事务操作已从多数提交数据的快照中读取。
如果事务是因果一致会话的一部分,写关注为"majority"且在事务提交后,可以确保事务操作已从多数提交数据的快照中读取,该快照提供了与紧接事务开始之前的操作的因果一致性。
可用性:
读关注"snapshot"仅可用于多文档事务。
对于分片群集上的事务,如果事务中的任何操作涉及已被禁用读关注“majority”的分片,那你就不能对该事务使用读关注"snapshot"。你只能对事务使用读关注"local""majority"

无论读关注级别如何,节点上的最新数据都可能无法反映系统中数据的最新版本

有关每个阅读关注级别的更多信息,请参见:

readConcern Support

Read Concern Option

对于不在多文档事务中的操作,你可以将 readConcern 级别指定为一个命令和方法的选项:

readConcern: { level: <level> }

要为 mongo shell方法 db.collection.find() 指定读关注级别,请使用 cursor.readConcern() 方法:

db.collection.find().readConcern(<level>)
事务和可用的读关注(Transactions and Available Read Concerns)

对于多文档事务,应在事务级别而不是在单个操作级别设置读关注。事务中的操作将使用事务级别的读关注。事务内部将忽略在集合和数据库级别设置的任何读关注。如果显式指定了事务级别的读关注点,则在事务内部也将忽略客户端级别的读关注点。

重要

不要为各个操作明确设置读关注。要设置事务的读关注,请参阅读 Read Concern/Write Concern/Read Preference

你可以在事务开始时设置读关注

如果未在事务开始时指定,则事务将使用会话级的读关注,或者如果未设置,则使用客户端级的读关注。

有关等多信息,请参考 事务的读关注.

因果一致的会话和可用的读关注(Causally Consistent Sessions and Available Read Concerns)

对于在因果一致的会话中的操作,"local" h和 "majority"级别可用。但是,为了保证因果一致性,你必须使用 "majority"。有关详细信息,请参见 因果一致性

如果多文档事务与因果一致的会话相关联,则"snapshot" 也可用于该事务。

支持读关注的操作(Operations That Support Read Concern)

下列的操作支持读关注:

重要

在为事务中的操作设置读关注时,请在事务级别而不是在单个操作级别设置读关注。不要在事务中明确的设置单独操作的读关注。更多信息,查看事务和读关注

Command/Method 命令/方法"local""available""majority""snapshot" [3]"linearizable"
count
distinct✓ [2]
find
db.collection.find() via cursor.readConcern()
geoSearch
getMore
aggregate db.collection.aggregate()✓ [1]
Session.startTransaction()
[1]你不能将$out 或者 $merge阶段与读关注的"linearizable"结合使用。也就是说,如果为db.collection.aggregate()指定"linearizable"读关注,则不能在管道中包括任何一个阶段。
[2]读关注"snapshot"仅适用于多文档事务。在事务中,不能在分片集合上使用distinct命令或其协助命令。

下列的写操作页能接受读关注,但必须是多文档事务的一部分:

重要

在为事务中的操作设置读关注时,请在事务级别而不是在单个操作级别设置读关注

Command 命令"local""available""majority""snapshot" [3]"linearizable"
delete
db.collection.deleteMany()
db.collection.deleteOne()
db.collection.remove()
findAndModify
db.collection.findAndModify()
db.collection.findOneAndDelete()
db.collection.findOneAndReplace()
db.collection.findOneAndUpdate()
insert
db.collection.insert()
db.collection.insertOne()
db.collection.insertMany()
update
db.collection.update()
db.collection.updateMany()
db.collection.updateOne()
db.collection.replaceOne()
[3]*(1, 2)*读关注“SNAPSHOT”仅适用于多文档事务,并且对于事务,您可以在事务级别设置读关注。支持“SNAPSHOT”的操作对应于事务中可用的CRUD操作。有关更多信息,请参见事务和读关注

注意事项

读自己的写(Read Your Own Writes)

在版本3.6中更改

从MongoDB 3.6版本开始,如果写请求确认,你可以使用因果一致的会话读你自己写入的内容。

在MongoDB 3.6之前,您必须使用 { w: "majority" } 写关注发出写操作,然后对读操作使用 "majority" 或者 "linearizable"读关注,以确保单个线程可以读取自己的写入内容

实时顺序(Real Time Order)

结合"majority" 写关注,"linearizable" 读关注使多个线程可以在单个文档上执行读写操作,就好像单个线程实时地执行了这些操作一样。 也就是说,这些读写的对应的计划被认为是线性的。

性能比较(Performance Comparisons)

"majority"不同,"linearizable" 的读关注通过从节点确认读操作正在从主节点读,该操作能够以{ w: "majority" }写关注来确认写入。 [4]因此,具有线性化读关注的读取可能比具有"majority""local"读关注的读慢得多。

为了避免万一大多数数据承载成员不可用,请始终将 maxTimeMS 与可线性化的读确认一起使用。maxTimeMS 确保操作不会无限期地阻塞,而是确保如果无法满足读取要求,则操作将返回错误。

例如:

db.restaurants.find( { _id: 5 } ).readConcern("linearizable").maxTimeMS(10000)

db.runCommand( {
     find: "restaurants",
     filter: { _id: 5 },
     readConcern: { level: "linearizable" },
     maxTimeMS: 10000
} )
[4]某些情况下,副本集中的两个节点可能会短暂地认为它们是主节点,但至多,其中一个节点将能够以{ w: "majority" }写关注完成。 可以完成{ w: "majority" }写入的节点是当前主节点,另一个节点是前主节点,由于网络分区的原因,该主节点尚未意识到其降级。 发生这种情况时,尽管请求的读优先级为主节点,但连接到前主界定啊的客户端仍可能会读到过时的数据,并且最终将对前主节点新写入的进行回滚。
Read Operations and afterClusterTime

3.6 版本新加入

MongoDB 3.6引入了对因果一致会话的支持。 对于与因果一致的会话相关联的读操作,MongoDB 3.6引入了 afterClusterTime 读关注选项,驱动程序会自动将afterClusterTime 读关注选项设置为与因果一致的会话相关联的操作。

重要

不要手动为读操作设置 afterClusterTime 。 MongoDB驱动程序会针对与因果一致的会话相关联的操作自动设置此值。 但是,您可以提前会话的操作时间和群集时间,以便与另一个客户端会话的操作保持一致。 有关示例,请参见示例

为了满足 afterClusterTime 值为T的读请求, mongod 必须在其oplog到达时间T之后执行请求。如果其oplog尚未达到时间T,则 mongod 必须等待服务该请求。

使用指定的 afterClusterTime 的读操作将返回满足读关注级别要求和指定的 afterClusterTime 要求的数据。

对于与因果一致会话无关的读操作,未设置 afterClusterTime

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值